Why Does React Sometimes Do Extra Work?
By default, React follows the " better safe than sorry " policy. If a parent component updates, React redraws all its children just in case. Usually this happens instantly, but if inside the child is a complex table of 1000 rows or a heavy chart, the application will start " lagging " .
1. React.memo: " Sign on the Door "
Imagine you're a manager (parent). You enter an employee's office (child component) with new instructions.
- Without memo: The employee drops everything, rereads all instructions, and redoes all the work, even if instructions haven't changed.
- With memo: The employee looks at the instructions. If they're exactly the same as yesterday, they say: " Boss, I already did this, take yesterday's result " .
const MyList = React.memo(({ items }) => {
// This code will only run if items changed
return <div>...</div>;
});
2. useMemo: Caching Calculations
Imagine you're solving a complex math problem. You spent an hour on it. If 5 minutes later you're asked the same example, you won't solve it again — you'll look at your notebook.
useMemo is your notebook.
const totalSum = useMemo(() => {
return hugeArray.reduce((acc, val) => acc + val, 0);
}, [hugeArray]); // Recalculate only if array changed
3. useCallback: The " New Reference " Trap
In JavaScript, functions are objects. And objects are compared by reference, not content.
// Yesterday's function: function() {}
// Today's function: function() {}
// Yesterday === Today? FALSE (references are different!)
Every time a component redraws, functions inside it are created anew. If you pass such a " new " function to React.memo, optimization breaks! The component will think: " Oh, they sent me a completely new function, need to redraw everything " .
useCallback is a way to tell React: " Save exactly this function reference and give it to me on every render, until I say otherwise " .
Memoization is not magic, but a compromise between processor speed and RAM consumption.