useReducer in ReactJS

dinesh priyantha
2 min readJul 9, 2024

--

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.

--

--