[React] useMemo && useCallback && React.memo


useMemo&なぜuseCallback(素子の特性)が必要なのか

  • 関数型素子はjsxを返す関数にすぎない.
  • 要素がロードされることは、関数(要素)を呼び出すことによって実行される人を指す.関数が実行されるたびに、内部宣言式が再宣言され、使用されます.
  • 構成部品は、ステータスの変更または親支柱の変更時に再ロードされます.親構成部品のステータスが変化すると、子構成部品も再ロードされます.(最適化しなければ)
  • useMemo

    const memoizedValue = useMemo(() => computedExpensiveValue(a, b), [a, b]);
    コアはメモリ化された値を返します.
    a,bの両方のpropsに上位素子から伝達された下位素子があると仮定し,下位素子はa,bを受け入れ,それぞれの値を異なる関数で加工し,新しい値を表示する役割を果たす.propsに渡されるパラメータが変化すると、サブエレメントが再レンダリングされます.props.a万変propsb呼び出し関数も再計算される.
    import React, { useMemo } from "react";
    
    const colorKor = useMemo(() => getColorKor(color), [color]);
    const movieGenreKor = useMemo(() => getMovieGenreKor(movie), [movie]);
    この場合、useMemoをインポートして加工関数と依存配列に渡すと、依存配列に渡される値が変化する場合にのみ、メモリ化された値が再計算されます.

    useCallback

    const memoizedCallback = useCallback(
      () => {
        doSomething(a, b);
      },
      [a, b],
    );
    コアはメモリ化を返す関数です.
    構成部品をロードするたびに、内部宣言式が再宣言され、使用されます.(構成部品のプロパティ2)構成部品内部の関数は変更されませんが、構成部品が再ロードされると再宣言されます.
    import React, { useState, useCallback } from "react";
    
    const onChangeHandler = useCallback(e => {
        if (e.target.id === "color") setColor(e.target.value);
        else setMovie(e.target.value);
      }, []);
    この場合、useCallbackをインポートして使用した関数の実行文を挿入することで、ロードされるたびに宣言されることを回避できます.依存配列に要素を追加すると、値を変更するときに要素を再宣言できます.
    アップエレメントの関数が再宣言されるたびに、その内容が同じであっても、ダウンエレメントの伝達関数が変化したとみなされます.このため、下端素子が反応する.最適化がmemo()などであり、コールバック関数がそのサブコンポーネントにpropsとして渡される場合、親コンポーネントからuseCallbackと宣言すると最適化に役立ちます.
    React.memo()を使用して関数型構成部品自体を囲む場合、渡されたpropsが変更されていない場合、親構成部品はメモリ化された関数型構成部品(以前にレンダリングされた結果)を使用します.
    詳細

    React.memo


    アップエレメントが再ロードされると、不変のダウンエレメントは再ロードを再び阻止し、エレメントを最適化することができる.重いコンポーネント(計算の実行、API要求、ブラウザイベントクエリーなど)は、アプリケーションの速度を遅くするため、最適化が必要です.そのためには、コメントを使用してください.
    // 하위컴포넌트
    import React, { memo, useEffect } from "react";
    
    function NormalComponent({ name }) {
      useEffect(() => { // 최적화되지 않으면 리랜더링 때마다 실행됨
        console.log("I rendered");
      });
      
      return <div>{name}</div>
    }
    
    export default memo(NormalComponent); // 컴포넌트를 memo()로 감싸줌
    memoを使用して最下位の構成部品をラップする場合は、構成部品が変更された場合にのみレンダリングされる構成部品に送信されるpropを覚えておいてください.
    つまりreact.memoがコンポーネントに関係ない場合は無効になります.
    React.memoはhookではなくHOCです.HOCは、Higher Orderコンポーネントの略であり、構成内の関数であり、パラメータとして構成部品を受け入れ、新しい構成部品を返します.クラス構成部品もパラメータとして使用できます.(useMemoはhookなので関数素子しか使えません)
    const NameTag = React.memo(
      (props) => <div>{props.name}</div>
    ,
      (prevProps, nextProps) => prevProps.name === nextProps.name
    )
    ブール値を返す関数を2番目のパラメータとして使用する場合は、関数の結果がfalseの場合にのみレンダリングを指定できます.(比較)

    整理する


    共通点:パフォーマンスの最適化は、不要なレンダリングまたは計算を制御することを目的としています.
    useMemo:前の値のhookを返し、前の値を記憶する条件に従って回収してパフォーマンスを最適化します(計算を減らし、再ロードを回避します)
    useCallback:関数の再生を防止する
    React.memo:シンボルツリーのレンダリングを防止したり、クラスコンポーネントを使用したりすることができます.