useCallback memoize function để giữ stable reference giữa renders.
Dùng khi truyền callback xuống child component được wrap bởi React.memo, hoặc khi function là dependency của useEffect.
tsx
const Parent = () => {
const [count, setCount] = useState(0)
// không dùng useCallback: handleClick mới mỗi render → Child luôn re-render
// dùng useCallback: reference ổn định → Child skip re-render nếu props khác không đổi
const handleClick = useCallback(() => {
console.log('clicked')
}, []) // deps rỗng vì không dùng state/props trong fn
return (
<>
<button onClick={() => setCount(c => c + 1)}>Parent count: {count}</button>
<MemoChild onClick={handleClick} />
</>
)
}
const MemoChild = React.memo(({ onClick }: { onClick: () => void }) => {
console.log('Child render')
return <button onClick={onClick}>Child</button>
})useCallback memoizes a function to maintain a stable reference between renders.
Use it when passing a callback to a child component wrapped with React.memo, or when a function is a dependency of useEffect.
tsx
const Parent = () => {
const [count, setCount] = useState(0)
// without useCallback: handleClick is new every render → Child always re-renders
// with useCallback: stable reference → Child skips re-render if other props unchanged
const handleClick = useCallback(() => {
console.log('clicked')
}, []) // empty deps because fn doesn't use any state/props
return (
<>
<button onClick={() => setCount(c => c + 1)}>Parent count: {count}</button>
<MemoChild onClick={handleClick} />
</>
)
}
const MemoChild = React.memo(({ onClick }: { onClick: () => void }) => {
console.log('Child render')
return <button onClick={onClick}>Child</button>
})