useReducer in ReactJS
useReducer
is a hook in React that is used for managing state in a more predictable and scalable way, especially when you have complex state logic that involves multiple sub-values or when the next state depends on the previous state.
Here’s a step-by-step guide on how to use useReducer
:
1. Define the Initial State
Define the initial state of your component.
const initialState = { count: 0 };
2. Define the Reducer Function
A reducer function takes the current state and an action and returns the next state. It should be a pure function, meaning it does not cause side effects.
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
case 'reset':
return initialState;
default:
throw new Error();
}
}
3. Use useReducer
in Your Component
Use the useReducer
hook inside your component, passing the reducer function and the initial state.
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
case 'reset':
return initialState;
default:
throw new Error();
}
}
const Counter = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
<button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
</div>
);
};
export default Counter;
Example
Here is a complete example that brings everything together:
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
case 'reset':
return initialState;
default:
throw new Error();
}
}
const Counter = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
<button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
</div>
);
};
export default Counter;
When to Use useReducer
useReducer
is particularly useful when:
- You have complex state logic that involves multiple sub-values.
- The next state depends on the previous state.
- You want a more predictable state transition, similar to how Redux works but in a more lightweight way.
useReducer
can make your state management logic more predictable and easier to test, especially when compared to using useState
for complex state management.