JAVASCRIPT
React Hook: useReducer for Complex State Logic
Leverage `useReducer` in React for managing complex state transitions, providing a robust and scalable alternative to `useState` for intricate component state.
import { useReducer } from 'react';
const initialState = { count: 0, loading: false, error: null };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { ...state, count: state.count + 1 };
case 'decrement':
return { ...state, count: state.count - 1 };
case 'reset':
return initialState;
case 'startLoading':
return { ...state, loading: true, error: null };
case 'stopLoading':
return { ...state, loading: false };
case 'setError':
return { ...state, loading: false, error: action.payload };
default:
throw new Error();
}
}
// How to use it:
/*
function ComplexCounter() {
const [state, dispatch] = useReducer(reducer, initialState);
const fetchData = async () => {
dispatch({ type: 'startLoading' });
try {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 1000));
if (Math.random() > 0.8) throw new Error('Failed to fetch!');
dispatch({ type: 'stopLoading' });
} catch (err) {
dispatch({ type: 'setError', payload: err.message });
}
};
return (
<div>
<h1>Count: {state.count}</h1>
{state.loading && <p>Loading...</p>}
{state.error && <p style={{ color: 'red' }}>Error: {state.error}</p>}
<button onClick={() => dispatch({ type: 'increment' })} disabled={state.loading}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })} disabled={state.loading}>-</button>
<button onClick={() => dispatch({ type: 'reset' })} disabled={state.loading}>Reset</button>
<button onClick={fetchData} disabled={state.loading}>Fetch Data</button>
</div>
);
}
*/
How it works: The `useReducer` hook is an alternative to `useState` for managing more complex state logic that involves multiple sub-values or where the next state depends on the previous one. It takes a `reducer` function (similar to Redux reducers) and an `initialState`. It returns the current state and a `dispatch` function. The `dispatch` function is used to send 'actions' to the reducer, which then computes and returns the new state, triggering a re-render. This pattern centralizes state updates, making them predictable and testable.