useContext & useReducer 🪝from component level state to global state!
[!Beginner Friendly] [Your initial step towards learning React Redux]
Table of contents
The useContext
hook is a way for a React component to access the context, or shared state, of a parent component. It is a convenient way to pass data down the component tree without having to use props at every level.
Here's an example of how to use the useContext
hook:
First, we need to create a context object using the React.createContext
function:
const MyContext = React.createContext();
Then, we can wrap a component in the MyContext.Provider
component, which allows us to pass a value prop to the context object:
<MyContext.Provider value={someValue}>
<MyComponent />
</MyContext.Provider>
Finally, in MyComponent
, we can use the useContext
hook to access the value prop of the context object:
const value = useContext(MyContext);
The useContext
hook will return the current value of the context object, which in this case is someValue
.
One important thing to note is that the context object will only update when the component re-renders. This means that if you want to update the context value, you will need to use the setState
hook or another method to trigger a re-render of the component.
Overall, the useContext
hook is a useful way to share state between components and avoid prop drilling, or the need to pass props down multiple levels of the component tree. It is particularly useful in cases where you have multiple components that need to access the same data.
The useContext
and useReducer
hooks are two powerful tools that can be used to manage state in a React application. While useState
is useful for managing state at the component level, useContext
and useReducer
allow you to manage global state and make it accessible to multiple components.
useContext
The useContext
hook is a way for a React component to access the context, or shared state, of a parent component. It is a convenient way to pass data down the component tree without having to use props at every level.
Here's an example of how to use the useContext
hook:
First, we need to create a context object using the React.createContext
function:
const MyContext = React.createContext();
Then, we can wrap a component in the MyContext.Provider
component, which allows us to pass a value prop to the context object:
<MyContext.Provider value={someValue}>
<MyComponent />
</MyContext.Provider>
Finally, in MyComponent
, we can use the useContext
hook to access the value prop of the context object:
const value = useContext(MyContext);
The useContext
hook will return the current value of the context object, which in this case is someValue
.
One important thing to note is that the context object will only update when the component re-renders. This means that if you want to update the context value, you will need to use the setState
hook or another method to trigger a re-render of the component.
Overall, the useContext
hook is a useful way to share state between components and avoid prop drilling, or the need to pass props down multiple levels of the component tree. It is particularly useful in cases where you have multiple components that need to access the same data.
useReducer
The useReducer
hook is similar to the useState
hook, but it is designed for managing state that is more complex or requires more logic to update. It is based on the Redux pattern of using reducers to manage state.
A reducer is a pure function that takes in the current state and an action, and returns a new state based on the action. It is called a "reducer" because it reduces a set of actions to a single value, which is the new state.
Here's an example of how to use the useReducer
hook:
First, we need to define a reducer function:
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
Then, we can use the useReducer
hook in our component to manage state using the reducer:
const [state, dispatch] = useReducer(reducer, { count: 0 });
The useReducer
hook takes in the reducer function and an initial state, and returns an array with the current state and a dispatch function.
To update the state, we can call the dispatch function and pass it an action object with a type field:
To continue the example, we can use the dispatch function in our component to update the state based on user interactions:
function handleIncrement() {
dispatch({ type: 'increment' });
}
function handleDecrement() {
dispatch({ type: 'decrement' });
}
return (
<div>
<button onClick={handleIncrement}>Increment</button>
<button onClick={handleDecrement}>Decrement</button>
<p>{state.count}</p>
</div>
);
In this example, we have two buttons that call the handleIncrement
and handleDecrement
functions when clicked. These functions dispatch actions to the reducer, which updates the state based on the action type.
One advantage of using the useReducer
hook is that it allows us to separate the logic for updating the state from the component itself. This can make our components easier to understand and test, and it can also make it easier to reuse the same logic in multiple components.
Another advantage of using the useReducer
hook is that it allows us to manage global state in our application. We can create a context object and wrap our root component in a Context.Provider
component, just like we did with the useContext
hook. Then, we can use the useContext
hook to access the global state and the dispatch function in any component that needs it.
In conclusion, the useContext
and useReducer
hooks are powerful tools for managing state in a React application. They allow us to share state between components and manage global state, making it easier to build complex and scalable applications.