useReducer
Keep every change to complex state in one tested function.
When state changes in several ways, such as a cart where you add, remove and clear items, put every change in one function called a reducer. It takes the current state and an action, and returns the new state.
Expected output
Pen x2, Book x1 1 60
A reducer has no React in it, so you can run and test it right here. In a component, useReducer connects it to the screen:
React (JSX)
import { useReducer } from "react";
export default function Cart() {
const [cart, dispatch] = useReducer(cartReducer, []);
const total = cart.reduce((sum, i) => sum + i.price * i.qty, 0);
return (
<section>
<button onClick={() => dispatch({ type: "add", item: { id: 1, name: "Pen", price: 10 } })}>Add pen</button>
<button onClick={() => dispatch({ type: "clear" })}>Clear</button>
<p>{cart.length} items, Rs {total}</p>
</section>
);
}- Use useState for a few independent values.
- Use useReducer when the next state depends on the previous one in several different ways.
- Never change cart inside the reducer. Always return a new array or object.