web-dev-qa-db-ja.com

React.ComponentとReact.PureComponent

公式 React docs は "React.PureComponentshouldComponentUpdate()はオブジェクトを浅く比較するだけ"と述べ、stateが "deep"の場合はこれに対して忠告します。

これを考えると、Reactコンポーネントを作成するときにReact.PureComponentを好む理由があるのでしょうか。

質問

  • React.Componentの使用にパフォーマンス上の影響がありますか?React.PureComponentの使用を検討する可能性がありますか?
  • PureComponentshouldComponentUpdate()は、浅い比較しか行わないと思います。このような場合、この方法はより深い比較には使用できませんか?
  • "さらに、React.PureComponentshouldComponentUpdate()はコンポーネントサブツリー全体のためのprop更新をスキップします" - これはpropの変更が無視されることを意味しますか?

それが助けになるなら、質問はこの 中ブログ を読むことから生じました。

163
semuzaboi

React.PureComponentReact.Componentの主な違いは、PureComponentが状態変化時に浅い比較をすることです。つまり、スカラー値を比較するときはそれらの値を比較しますが、オブジェクトを比較するときは参照のみを比較します。アプリのパフォーマンスを向上させるのに役立ちます。

以下の条件のいずれかを満たすことができるときあなたはReact.PureComponentのために行くべきです。

  • 状態/小道具は不変のオブジェクトであるべきです
  • 州/小道具は階層構造を持つべきではありません
  • データが変わったらforceUpdateを呼ぶべきです

React.PureComponentを使っているのなら、すべての子コンポーネントも純粋であることを確認するべきです。

react.PureComponentの使用を検討した場合、React.componentの使用にパフォーマンスへの影響はありますか?

はい、アプリのパフォーマンスが向上します(比較が浅いため)。

PurecomponentのshouldComponentUpdate()は、浅い比較しか行わないと思います。このような場合、上記の方法はより深い比較に使用できないでしょうか。

あなたはそれを正しく推測しました。あなたが私が上で述べた条件のいずれかを満たすならば、あなたはそれを使うことができました。

「さらに、React.PureComponentのshouldComponentUpdate()は、コンポーネントのサブツリー全体に対してプロップの更新をスキップします」 - プロップの変更が無視されるという意味ですか?

はい、プロップの変更は、浅い比較で違いが見つからない場合は無視されます。

212
vimal1083

ComponentPureComponentは違いが1つあります。

PureComponentは、Componentメソッドを処理する点を除いて、shouldComponentUpdateとまったく同じです。

小道具や状態が変わると、PureComponentは小道具と状態の両方で浅比較を行います。一方、Componentでは、現在の小道具と状態を箱から出して次の状態と比較することはできません。したがって、shouldComponentUpdateが呼び出されるたびに、コンポーネントはデフォルトで再レンダリングされます。

浅い比較

前の小道具と状態を次の小道具と比較するとき、浅い比較はプリミティブが同じ値を持ち(例えば、1が1に等しい、またはtrueがtrueに等しい)、オブジェクトや配列のようなより複雑なJavaScript値の間で参照が同じであることをチェックします。

出典: https://codeburst.io/when-to-use-component-or-purecomponent-a60cfad01a81

13

主な違いは、私が見ているように、コンポーネントの小道具と状態が変わったかどうかにかかわらず、コンポーネントはその親が再描画するたびに再描画されることです。

一方、純粋なコンポーネントは、その純粋なコンポーネントの小道具(または状態)が変更されていない限り、その親が再レンダリングしても再レンダリングされません。

たとえば、親、子、孫という3レベルの階層を持つコンポーネントツリーがあるとします。

1人の子供だけの小道具が変更されるように親の小道具が変更されると、次のようになります。

  • すべてのコンポーネントが通常のコンポーネントの場合、コンポーネントツリー全体がレンダリングされます。
  • すべての子と孫が純粋なコンポーネントである場合は、小道具が変更されたかどうかに応じて、1人の子とその孫の1人またはすべてが再表示されます。このコンポーネントツリーに多数のコンポーネントがある場合は、パフォーマンスが大幅に向上する可能性があります。

ただし、純粋なコンポーネントを使用しても影響がないことがあります。私は親がその店の小道具から小道具を受け取って、その子供の小道具の複雑な計算を実行する必要があったときに私はそのような事件を経験しました。親はフラットリストを使って子をレンダリングしました。

その結果、reduxストアに少しでも変更があるたびに、子供のデータのフラットリスト配列全体が再計算されました。つまり、値が変わらなくても、ツリー内のすべてのコンポーネントに対して、小道具は新しいオブジェクトでした。

この場合、純粋なコンポーネントは役に立ちません、そしてパフォーマンスの向上は、通常のコンポーネントを使用し、再レンダリングが必要な場合はshouldComponentUpdateで子をチェックインすることによってのみ達成できます。

6
Yossi