为了子组件不必要的重复渲染,React 使用 memo
/ useMemo
/ useCallback
进行缓存处理。
它们分别解决了两个问题:
防止 props 不变时的重复渲染
防止 props 自身不必要的变化
其中,memo
和 useMemo
/ useCallback
需要同时使用,否则实际上起不到缓存的效果。
memo 的使用
memo
的出现,使得子组件只有在 props
变化时才会被重新渲染,也就解决了“props 不变时的重复渲染”的问题。
function Children({ count }) {
return <div>{count}</div>;
}
// 缓存组件
const MemoChildren = memo(Children);
function Container() {
const [count, setCount] = useState(0);
return (
<div>
<MemoChildren count={count} />
<button onClick={() => setCount((count) => count + 1)}>+</button>
</div>
);
}
useMemo 和 useCallback
这两个 hooks 都是在对 state 进行缓存,不同的是一个存变量、一个存函数。它们在父组件里缓存要传递给子组件的变量,起到了“防止 props 自身不必要的变化”的作用。
function Children({ count, cb }) {
return (
<div>
<span>{count}</span>
<button onClick={() => cb(count + 1)}>+</button>
</div>
);
}
const MemoChildren = memo(Children);
function Container() {
const [count, setCount] = useState(0);
const value = useMemo(() => count + 3, [count]);
const handleCb = useCallback(() => {
setCount(count - 3);
}, []);
return <MemoChildren count={value} cb={handleCb} />;
}
注意:如果传递给 MemoChildren
的变量没有用 useMemo
和 useCallback
,父组件每次都会产生新的变量和函数,props 就会一直变化,即使有 memo
也无法起到缓存作用