Reactレンダリングを最適化する方法(+React.memo、useMemo、useCallbackを理解)

6016 ワード

インスタグラムのクローン作成を完了しましたが、
最適化についてもっと知りたいです.
useMemo, useCallback, React.memoを整理したり、勉強したり、使い方を考えたりします.
👑 反応傾向の方向性を最適化
リアクターには、上から下への一方向のデータストリームがあり、データの変化によって要素がレンダリングされます.
1.ステータスとpropsの変更を最小化
2.ステータスおよびpropsの変更による不要なサブエレメントツリーレンダリングの最小化
この方向のために、どんな方法が使えますか?
👑 反応傾向の提示方法を最適化する
💎 stateは、このstateを使用する最上位コンポーネントに宣言します.
ある状態が変化すると、リアクターはその状態を宣言する要素とそのサブ要素を再レンダリングします.
💎 オブジェクトタイプのステータスを宣言に最大限に分割
オブジェクトが大きく複雑な構造であれば、分割できるだけ分割します.
サブエレメントがこの状態で一部のプロパティのみを使用している場合は、そのプロパティの変更時にのみ再レンダリングすることが望ましい.
どうしてですか.
分割せずにオブジェクトの状態を使用すると、サブアセンブリは一部のPropertyのみを使用しますが、他のProperty値を更新すると再レンダリングされます.
💎 構成部品をマッピングする場合、キー値としてインデックスは使用されません.
間に別の要素を挿入すると、その後のすべての要素がインデックスを変更します.
したがって、キー値の変更に伴い、再マウントが発生します.
また,keyとデータが一致しないため,相互にインターリーブする副作用も生じる.
💎 サブコンポーネントのpropsにオブジェクトを渡す場合は、新しいオブジェクトの作成に注意してください.
サブエレメントのprops値にオブジェクトを渡す場合は、コンストラクション関数やオブジェクトテキストなどの新しいオブジェクトをエレメントに作成して渡すことに注意してください.
宣言されたpropsまたはstateを参照せずに、新しいオブジェクトをサブコンポーネントに直接渡す場合、コメントは実行できません.新しく作成されたオブジェクトは、前のオブジェクトとは異なる参照アドレスを持つオブジェクトであるためです.
したがって、stateをそのままサブアセンブリに渡し、サブアセンブリに必要なデータ加工を行うことが望ましい.
Memoization이전 값을 메모리에 저장해 동일한 계산의 반복을 제거해 빠른 처리를 가능하게 하는 기술次に学ぶ3つはこのMemoizationをベースにしています.
💎 useMemo
関数の結果値を記憶し、不要な演算を排除します.
関数呼び出し後、戻り値が記憶され、2番目のパラメータ依存配列の要素が変更されるたびに、1番目のパラメータのcallback関数が再生成されます.
なぜ使うのですか?
この関数は、特定の状況で実行する必要があり、要素のレンダリング条件に基づいて継続的に実行する必要がある場合に使用して防止できます.
userMemoはhookで、コメント値を返します.
パラメータで関数と依存値を受信し、いずれかの依存因子が変化した場合、値を再計算します.
依存関係に何も渡さない場合は、レンダリングのたびに値が再計算されて返されます.
function NameTag(props) {
  return useMemo(
    () => <div>{props.name}</div>
  ,
    [props.name]
  )
}
💎 React.memo
Highter Order Components(HOC).
エレメントをパラメータとして受信し、新しいエレメントの関数を返します.
コンポーネントが同じpropsを受け取ったときに同じ結果がレンダリングされた場合、React.memoを使用すると、不要な構成部品のレンダリングを防止できます.
リアクターは、最後にレンダリングした結果を再使用します.
  • 道具に変更がないかチェックmemoで囲まれた関数型構成部品が関数内部でusStateやuseContextなどのhookを使用している場合、stateやcontextを変更するたびに再レンダリングされます.
  • const NameTag = React.memo(
      (props) => <div>{props.name}</div>
    ,
      (prevProps, nextProps) => prevProps.name === nextProps.name
    )
    propsが変更され、不要なレンダリングが発生しているかどうかを確認するにはどうすればいいですか?
    ステータスが新しい構成部品を変更またはレンダリングする場合は、浅いコピーで同じ値かどうかを判断し、レンダリングするかどうかを決定します.
    したがって,同じ値のpropsであっても,素子の状態が変化すると,浅い複製で新しい値として認識される.
    propsが関数、オブジェクト、配列などの参照タイプであり、同じ参照タイプでない場合は、新しい値と判断します.この場合、再レンダリングは不要になります.
    React.memoはいつ書きますか?
  • Pure Functional omponent
  • Renderingが頻繁に発生する場合、
  • 再レンダリング中に同じprops値を渡し続ける
    4つのUI要素が多数含まれる構成要素の場合、
  • react dev toolsを使用してレンダリング状況を表示し、適用するかどうかを決定したほうがいいです.
    React.memoの限界
    関数propsをサブコンポーネントに渡す方法を考えてみましょう.
    関数の内容が同じで、参照値が異なる場合は、レンダリングのたびに新しい参照値が得られます.
    前述の理由により参照値が異なる場合はReact.memoを使用しても、他のアイテムとして認識されてレンダリングされます.
    つまり、回顧録を行ってもレンダリングが発生し、メモリが浪費され、本来の目的を達成できないということです.
    では何で補うの?
    💎 useCallback
    使用前const increment1 = () => setCount1(c => c + 1);使用後const increment1 = React.useCallback(() => setCount1(c => c + 1), []);useMemoは、特定の値を再使用するためのhookです.
    useCallbackは、特定の関数を再利用するためのhookです.
    関数をpropsとしてサブエレメントに提供する場合は、useCallbackを使用して再レンダリングを回避することが望ましい.
    上記の問題はuseCallback関数でcallback関数を同じcallbackインスタンスに設定することで解決できます.
    常に同じ関数インスタンスを返すのでReact.memoは正常な機能を実行します.
    Reference
  • https://ssangq.netlify.app/posts/react-memo-useMemo-useCallback
  • https://react.vlpt.us/basic/19-React.memo.html
  • https://simsimjae.tistory.com/404?category=384814
  • https://cocoder16.tistory.com/36