Introduction
When I started learning React, I mostly used useState for everything. It worked well in the beginning, but as my project became a little bigger, managing state became confusing. I had multiple values, and sometimes one value depended on another. That is when I started learning about useReducer and useMemo.
In this blog, I will explain both in a simple way based on my understanding as a beginner.
useReducer
useReducer is a React Hook used to manage state in a more structured way. Instead of directly updating state like in useState, we use a separate function called a reducer. This function decides how the state should change.
The basic syntax looks like this:
const [state, dispatch] = useReducer(reducer, initialState);
Here, state stores the current value, and dispatch is used to send an action. The reducer function takes the current state and the action, and returns a new state.
A simple reducer function looks like this:
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
When I first saw this, it looked confusing, but later I understood that the action simply tells what needs to be done. For example, if I want to increase the count, I can write:
dispatch({ type: "increment" });
This will call the reducer and update the state.
Using it inside a component looks like this:
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<h2>{state.count}</h2>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
</div>
);
One thing I understood is that useReducer is very useful when state values are connected. For example, if I have count and total, and total depends on count, it is better to manage both together instead of using separate useState calls.
function reducer(state, action) {
switch (action.type) {
case "update":
return {
count: state.count + 1,
total: state.total + state.count
};
default:
return state;
}
}
This makes the logic easier to manage in one place.
useMemo
After learning useReducer, I faced another issue. My component was re-rendering again and again, and some calculations were running even when they were not needed. That is when I learned about useMemo.
useMemo is used to improve performance. It stores the result of a calculation and only recalculates it when required.
The syntax is simple:
const value = useMemo(() => {
return calculation;
}, [dependencies]);
At first, I did not understand what dependencies mean. Later I realized that dependencies are the values that control when the function should run again.
Here is a simple example:
const result = useMemo(() => {
console.log("calculating");
return count * 2;
}, [count]);
In this example, the calculation runs only when count changes. If I update some other value like text input, this function will not run again.
const [count, setCount] = useState(0);
const [text, setText] = useState("");
const result = useMemo(() => count * 2, [count]);
return (
<div>
<h2>{result}</h2>
<button onClick={() => setCount(count + 1)}>Increase</button>
<input value={text} onChange={(e) => setText(e.target.value)} />
</div>
);
When I type in the input field, the component re-renders, but the calculation does not run again. This is how useMemo helps improve performance.
Top comments (0)