- Use the Context API to avoid prop drilling
- Create a custom context with React
- Wrap components in a Provider to share state
- Consume context data using useContext
- Pass multiple values through context
- The Provider pattern allows us to pass values to comonents without passing it down through props.
- Pre-configuration: Open your terminal, navigate to the root of the project directory, and type
npm i. This will install and configure all the necessary packages. - Run
npx json-server --watch db.jsonin the terminal - Open a second terminal and run
npm run dev
- Create a context
- In the
contextfolder, create a file calledRestaurantContext.jsx. - Import
createContextanduseContextfrom React. - Call
createContext()and assign the result to a variable namedRestaurantContext. - Define a custom hook called
useRestaurants. Inside the function, passRestaurantContexttouseContextand return the result. - Export both
RestaurantContextanduseRestaurants.
import { createContext, useContext } from "react";
export const RestaurantContext = createContext();
export const useRestaurants = () => useContext(RestaurantContext);
- Wrap App in the Provider
-
Import
RestaurantContextfromRestaurantContext.jsx. -
Use
RestaurantContext.Providerto create a context provider component. Treat this as a parent component and wrap your entire app’s JSX inside it. -
The context is given values through the value prop. Use double curly braces ({{}}) to pass both
restaurantStateandupdateRestaurantsinto the provider.
import { RestaurantContext } from "./context/RestaurantContext";
// Other code from App....
return (
<RestaurantContext.Provider
value={{ restaurants: restaurantState, updateRestaurants }}
>
<div className="App">
<AddRestaurant />
<RestaurantsContainer />
</div>
</RestaurantContext.Provider>
);
- Access context in child components
- In
RestaurantsContainer, import theuseRestaurantshook. - Just like with state, destructure the
restaurantsvalue fromuseRestaurants. - In
AddRestaurant, import and useuseRestaurantsto destructureupdateRestaurants.
//Solutoin for Importing context to AddRestaurant should look similar.
import Restaurant from "./Restaurant";
import { useRestaurants } from "../context/RestaurantContext";
function RestaurantsContainer() {
const { restaurants } = useRestaurants();
return (
<div className="restaurantContainer">
{restaurants.map((restaurant) => (
<Restaurant key={restaurant.id} restaurant={restaurant} />
))}
</div>
);
}
export default RestaurantsContainer;