React Context API - Complete Guide
A comprehensive guide to React Context API for state management, including providers, consumers, and custom hooks.
React Context API - Step by Step by Sandeep Prasad​
Step 1. Create the Context​
- You can also set a default value in the context.
import { createContext } from "react";
// Create the context
export const MyContext = createContext("default value");
Step 2. Create a Provider​
- The provider is responsible for passing data down to the components that need it.
// MyContextProvider.jsx
import { MyContext } from "./MyContext";
import { useState } from "react";
// Create a provider component
export const MyContextProvider = ({ children }) => {
const [value, setValue] = useState("Initial Value");
return (
<MyContext.Provider value={{ value, setValue }}>
{children}
</MyContext.Provider>
);
};
- you can use step 1 and 2 in single file
Step 3. Wrap Your App with the Provider​
- Wrap the root of your app or any component tree that needs access to the context.
// index.js
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import { MyContextProvider } from "./MyContextProvider";
ReactDOM.createRoot(document.getElementById("root")).render(
<MyContextProvider>
<App />
</MyContextProvider>
);
Step 4. Consuming Context Data​
- Use
useContextin any child component to access the context values.
// MyComponent.jsx
import { useContext } from "react";
import { MyContext } from "./MyContext";
const MyComponent = () => {
const { value, setValue } = useContext(MyContext);
const handleChange = () => {
setValue("New Value");
};
return (
<div>
<p>Current Value: {value}</p>
<button onClick={handleChange}>Change Value</button>
</div>
);
};
export default MyComponent;
Step 5. Accessing Default Values (Optional)​
- If a component is not wrapped in a provider, it will use the default value set in
createContext.
const value = useContext(MyContext);
Step 6. Creating a Custom Hook for Context (Optional)​
- Instead of using useContext directly in your components, you can create a custom hook that wraps around it. This will make your context consumption more reusable and abstracted.
// useMyContext.jsx
import { useContext } from "react";
import { MyContext } from "./MyContext";
// Custom hook for accessing MyContext
export const useMyContext = () => {
const context = useContext(MyContext);
// If the context is undefined, it means that the component is not wrapped with the provider.
if (!context) {
throw new Error("useMyContext must be used within a MyContextProvider");
}
return context;
};
- Now, instead of calling useContext(MyContext) directly in your components, you can use the seMyContext hook.
// MyComponent.jsx
import { useMyContext } from "./useMyContext";
const MyComponent = () => {
const { value, setValue } = useMyContext();
const handleChange = () => {
setValue("New Value");
};
return (
<div>
<p>Current Value: {value}</p>
<button onClick={handleChange}>Change Value</button>
</div>
);
};
export default MyComponent;
};
Recap:​
- Create Context with
createContext()and export it. - Create Provider to pass down values and wrap the necessary part of your app.
- Wrap Your App with the Provider so components can access the context.
- Consume Context using
useContext()inside any component that needs it.