Rules of Hooks
- Call only at top level
Because React must call all Hooks in the same order every render - Call only inside React functions
When to re-render
- React re-renders when state or props change
- Hooks themselves don’t “render”; only state updates do
- Or the parent components re-render but the child doesn’t use
useCallBackoruseMemo
✅ Triggers Re-render
useState→ whensetStatechanges valueuseReducer→ when new state differsuseContext→ when context updates
❌ Does NOT Trigger Re-render
useRef→ mutable value holderuseEffect→ runs after render
*useEffectruns for extra logic such as fetching data. Only trigger re-render whensetStateinsideuseEffectis calleduseMemo/useCallback→ just memoize values/functions
React.memo & useMemo & useCallback
- Use
useMemoanduseCallbackto avoid unecessary re-render - ⚛️ React.memo + useCallback + useMemo Example
import React, { useState, useCallback, useMemo } from "react";
const Child = React.memo(({ onClick, value }) => {
return <button onClick={onClick}>{value}</button>;
});
export default function App() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => setCount(c => c + 1), []);
const label = useMemo(() => `Count: ${count}`, [count]);
return <Child onClick={handleClick} value={label} />;
}
useMemocaches a computed value inside a component to avoid re-calculating it on every render.React.memocaches a component’s rendered output (child component) to avoid re-rendering when its props haven’t changed.- In this example,
handleClickonly render once when this parent component first created. ThereforeChildonly re-render whencountchange
Event loop & batch update
- In JavaScript, synchronous code always runs first, and asynchronous code executes after the current synchronous tasks finish in the next event loop cycle.
- Batch update = combine multiple state updates into one render for better performance.
- In React 18, automatic batching applies to all state updates —
useState,useReducer, and class componentsetState setCount(count+1)only update the old value in a same render cycle, might cause bugssetCount(c => c + 1)uses a functional update, it always reads the latest state value, preventing bugs when multiple updates happen quickly or in the same render cycle.
Leave a Reply