为了子组件不必要的重复渲染,React 使用 memo / useMemo / useCallback 进行缓存处理。
它们分别解决了两个问题:
-
防止 props 不变时的重复渲染
-
防止 props 自身不必要的变化
其中,memo 和 useMemo / useCallback 需要同时使用,否则实际上起不到缓存的效果。
memo 的使用
memo 的出现,使得子组件只有在 props 变化时才会被重新渲染,也就解决了“props 不变时的重复渲染”的问题。
jsxfunction 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 自身不必要的变化”的作用。
jsxfunction 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 也无法起到缓存作用
Article Index