useCallback フックは、戻り値ではなく関数自体をメモ化します。 useCallback は関数参照をキャッシュします
コンポーネント内で宣言された関数は、変数と同様に、レンダリングのたびに再作成されます。違いは、毎回異なる参照を使用してレンダリングされることです。ということで、
この関数に依存する useEffect は、レンダリングのたびに再度実行されます:
import React, { useState, useEffect, useCallback } from 'react'; // Parent Component const ParentComponent = () => { const [count, setCount] = useState(0); const [text, setText] = useState(""); // Function declared inside the component const handleClick = () => { setCount(count + 1); }; // useEffect depending on handleClick useEffect(() => { console.log("handleClick changed, running useEffect"); }, [handleClick]); return ( <div> <button onClick={handleClick}>Increment Count</button> <p>Count: {count}</p> <ChildComponent handleClick={handleClick} /> </div> ); }; // Child Component const ChildComponent = React.memo(({ handleClick }) => { console.log("ChildComponent re-rendered"); return <button onClick={handleClick}>Child Increment</button>; }); export default ParentComponent;
子コンポーネントでも同様のことが起こります:
別のコンポーネントの子として、高価な、または「遅い」レンダリング ロジックを持つコンポーネントがある場合、親コンポーネントがレンダリングされるたびに、そのすべての子も再レンダリングされます。
これらの不必要な再レンダリングを防ぐために、React.memo を使用できます。この上位コンポーネントは子コンポーネントをキャッシュし、プロパティが実際に変更された場合にのみ再レンダリングされるようにします。ただし、関数を小道具として渡す場合には微妙な問題があり、それにより、子が再レンダリングされるべきではない場合でも再レンダリングされてしまいます。
関数参照の問題
App の子として SlowComponent があると想像してください。アプリには、ボタンのクリック時に状態が変化し、アプリの再レンダリングがトリガーされます。 SlowComponent のプロパティは変更していませんが、クリックするたびに再レンダリングされます。
なぜですか?レンダリングのたびに、handleClick 関数が新しい参照で再作成され、React は変更されたプロップとして解釈し、SlowComponent の再レンダリングを引き起こします。これを修正するには、useCallback フックを使用して、レンダリング間で関数の参照をキャッシュします。
useCallback を使用した解決策
handleClick を useCallback 内にラップすることで、特定の依存関係が変更された場合にのみ再作成するように React に指示します。構文は次のとおりです:
const cachedFn = useCallback(fn, [dependencies]);
この例での useCallback の適用
useCallback を使用して App コンポーネントを最適化する方法を見てみましょう:
import React, { useState, useCallback } from "react"; const App = () => { const [count, setCount] = useState(0); const [value, setValue] = useState(""); // Wrapping handleClick with useCallback to cache its reference const handleClick = useCallback(() => { setValue("Kunal"); }, [setValue]); return ( <div> <button onClick={() => setCount(count + 1)}>Increment Count</button> <p>Count: {count}</p> <SlowComponent handleClick={handleClick} /> </div> ); }; const SlowComponent = React.memo(({ handleClick }) => { // Intentially making the component slow for (let i = 0; i < 1000000000; i++) {} console.log("SlowComponent re-rendered"); return <button onClick={handleClick}>Click me in SlowComponent</button>; }); export default App;
useCallback を使用する場合
以上がReactjs の useCallback を理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。