memo、useCallback、useMemoとuseEffectは違います.


問題の導入
サブコンポーネントのは、着信したname属性だけに依存しているが、親コンポーネントname属性とtext属性の変化は、いずれもPartent関数の再実行をもたらし、したがって、着信したサブアセンブリpropsが変化していなくても、サブアセンブリが任意のprops属性に依存していないため、サブアセンブリが新たにレンダリングされることになる.
const Child = ((props: any) => {
    console.log("     ...");
    return (
        

text:{props.name}
{new Date().getTime()}
) }) const Parent = () => { const [count, setCount] = useState(0); const [text, setText] = useState("") const handleClick = () => { setCount(count + 1); } const handleInputChange = (e) => { setText(e.target.value) } return (
count:{count}
) }
モモ
memoパッケージを使用する場合は、プロpsが変更されたサブコンポーネントだけが再レンダリングされます.memoを使うと、一定の性能が向上します.
const Child = memo((props: any) => {
    console.log("     ..."); //    props    , name     ,         
    return (
        

text:{props.name}
{new Date().getTime()}
) }) const Parent = () => { const [count, setCount] = useState(0); const [text, setText] = useState("") const handleClick = () => { setCount(count + 1); } const handleInputChange = (e) => { setText(e.target.value) } return (
count:{count}
) }
しかし、導入されたプロpsが関数を含む場合、親コンポーネントは毎回新たな関数を作成するので、伝達関数サブコンポーネントはまた、関数の内容が同じであっても再レンダリングされる.どうやってこの問題を解決しますか?私たちは関数をキャッシュしたいので、アメリカのCallbackを導入します.
const Child = memo((props: any) => {
    console.log("     ..."); //       count  ,       ,handleInputChange          ,          
    return (
        

text:{props.name}
{new Date().getTime()}
) }) const Parent = () => { const [count, setCount] = useState(0); const [text, setText] = useState("") const handleClick = () => { setCount(count + 1); } const handleInputChange = (e) => { setText(e.target.value) } return (
count:{count}
) }
useCallback
useCallbackはキャッシュ関数として使用され、依存項が変更された場合にのみ、関数が新しい関数に戻ります.親コンポーネントの関数がpropsとしてサブアセンブリに伝達された場合、親コンポーネントのデータが変更され、関数が再実行される限り、プロpsの関数として新しいインスタンスが生成され、サブアセンブリのリフレッシュにuseCallbackを使用して関数をキャッシュすることができます.memoを組み合わせて使う必要があります.

const Child = memo((props: any) => {
    console.log("     ..."); 
    return (
        

text:{props.name}
{new Date().getTime()}
) }) const Parent = () => { const [count, setCount] = useState(0); const [text, setText] = useState("") const handleClick = () => { setCount(count + 1); } const handleInputChange =useCallback((e) => { setText(e.target.value ) },[]) return (
count:{count}
) }
useCallbackの二つ目のパラメータ依存項はどのような場合に使いますか?次の例を見てください.
//  handleInputChange
const handleInputChange =useCallback((e) => {
        setText(e.target.value + count)
    },[]) 
上記の例でcountが変わるとどうなりますか?countは変更されましたが、handleInput Changeは任意の項目に依存しませんので、handleInput Changeは初期化時に関数を呼び出すだけでキャッシュされます.テキストが変更された時やcountが変更された時に関数内部のcountは常に0です.したがって、countを依存項に追加し、countが変化したら新たな関数を生成し、関数内部のcount値を変更する必要があります.
const handleInputChange =useCallback((e) => {
        setText(e.target.value + count)
    },[count])
use Memo
useMemoの使用シーンは以下の例を見てください.getTotalは非常に高価な動作であると仮定しますが、この関数の結果はcountとpriceにのみ依存します.しかし、色の変化によって、DOM再レンダリングもその関数の実行につながります.useMemoはこの関数をキャッシュするための実行結果です.依存項が変更された場合のみ再計算されます.

const Parent = () => {
    const [count, setCount] = useState(0);
    const [color,setColor] = useState("");
    const [price,setPrice] = useState(10);
    const handleClick = () => {
        setCount(count + 1);
    }
    const getTotal = ()=>{
        console.log("getTotal exec ...") //       count price, color            
        return count * price
    }
    return (
: setColor(e.target.value)}/>
: setPrice(Number(e.target.value))}/>
:{count}
:{getTotal()}
) }
修正後は以下の通りです.useMemoキャッシュのは関数実行の結果です.
const Parent = () => {
    console.log("parent exec...")
    const [count, setCount] = useState(0);
    const [color,setColor] = useState("");
    const [price,setPrice] = useState(10);
    const handleClick = () => {
        setCount(count + 1);
    }
    const getTotal = useMemo(()=>{
        console.log("getTotal exec ...") 
        return count * price
    },[count, price])
    return (
: setColor(e.target.value)}/>
: setPrice(Number(e.target.value))}/>
:{count}
:{getTotal}
) }
useMemoとuseEffectは違います.
以上のuseMemoの例もuseeffectを使って実現できます.useffectを使って書き換えた結果です.
const Parent = () => {
    console.log("parent exec...")
    const [count, setCount] = useState(0);
    const [color,setColor] = useState("");
    const [price,setPrice] = useState(10);
    const [total,setTotal] = useState(0)
    useEffect(()=>{
        setTotal(price * count)
    },[price,count])
    const handleClick = () => {
        setCount(count + 1);
    }
    
    return (
: setColor(e.target.value)}/>
: setPrice(Number(e.target.value))}/>
:{count}
:{total}
) }
なお、useffectはprice、countのいずれかの変化後にトリガされ、totalが変更されると、関数の再実行がトリガされ、コンポーネントが再レンダリングされるので、制御セットでは「parent exec...」が2回印刷され、最初の例では「parent exec...」が表示されます.一回だけ印刷されたので、以下のようにまとめられています.useffectはDOM変更後にトリガされ、useMemoはDOM再レンダリングの前にuseEffect設定値をトリガすると再レンダリングされますが、useMemoは再レンダリングされません.