14

この質問は、React 0.14 に関するリリース ノート (およびその他の関連する誇大広告) を読んで以来、頭の中でぐるぐる回っています。私は React の大ファンであり、ステートレス コンポーネント ( https://facebook.github. io/react/blog/2015/09/10/react-v0.14-rc1.html#stateless-function-components ) は、そのようなコンポーネントを書きやすくすることと、これらのコンポーネントの意図をコードで表現することの両方の点で優れたアイデアです。コンポーネントは、同じ小道具データに対して一貫してレンダリングするという点で「純粋」でなければなりません。

問題は、React がこれらのステートレス コンポーネント関数を完全に独り占めせずに最適化し、props 参照がコンポーネント内で操作されるべきではないという点で不変であるだけでなく、決して変更できないと仮定することをどのように可能にするかです。コンポーネントのライフサイクル外?「通常の」コンポーネント (別名ステートフル コンポーネント - つまり、ライフサイクル全体を通過するコンポーネント、componentWillMount、getInitialState など) にオプションの「shouldComponentUpdate」機能がある理由は、Reactすべての小道具と状態の参照は完全に不変であると仮定します。コンポーネントがレンダリングされた後、props 参照の特定のプロパティが変更される可能性があるため、同じ「props」インスタンスが後で異なる内容を持つ可能性があります。これが部分的には、完全に不変な構造の使用に多くの興奮があった理由であり、React で Om を使用するとパフォーマンスが大幅に向上する可能性があると言われている理由の 1 つです。そこで使用される不変の構造により、任意のオブジェクトの特定のインスタンスが決して変更されないことが保証されるため、 shouldComponentUpdate は小道具と状態に対して非常に安価な参照等価性チェックを実行できます ( http://swannodette.github.io/2013/12/17/the -future-of-javascript-mvcs/ )。

私はこれについてより多くの情報を見つけようとしていますが、どこにもありません。props データが不変の型で構成されると仮定せずに、ステートレス コンポーネントの周りでどのようなパフォーマンスの改善を行うことができるかを想像することはできません.おそらく、不変でない props 型の予備分析を行って、「props」と「nextProps」が同じデータ?

誰かが内部情報や、これに関する啓発的な洞察を持っているかどうか疑問に思いました. Reactが props 型を「完全に不変」にすることを要求始めた場合 (データが変更されていないことを確認するために参照の等価性比較を許可する)、それは大きな前進だと思いますが、大きな変化になる可能性もあります。

4

4 に答える 4

3

コンポーネントはそのパラメータの純粋な関数であるため、キャッシュするのは簡単です。これは、純粋関数のよく知られた特性によるものです。同じ入力に対して、それらは常に同じ出力を返します。それらはパラメーターのみに依存するため、内部または外部の状態には依存しません。その関数内で状態変化として解釈される可能性のある外部変数を明示的に参照しない限り。

ただし、関数コンポーネントがいくつかの外部変数を読み取って戻り値を構成する場合、キャッシュは不可能です。そのため、これらの外部変数は時間の経過とともに変化し、キャッシュされた値が廃止される可能性があります。とにかく、これは純粋な関数であることの違反であり、もはや純粋ではありません。

React v0.14 Release Candidateページで、Ben Alpert は次のように述べています。

このパターンは、アプリの大部分を構成するこれらの単純なコンポーネントの作成を促進するように設計されています。将来的には、不要なチェックやメモリ割り当てを回避することで、これらのコンポーネントに固有のパフォーマンスを最適化できるようになる予定です。

彼が純粋な機能コンポーネントのキャッシュ可能性を意味していたことは間違いありません。

デモンストレーション用の非常に単純なキャッシュの実装を次に示します。

let componentA = (props) => {
  return <p>{ props.text }</p>;
}

let cache = {};
let cachedA = (props) => {
  let key = JSON.stringify(props); // a fast hash function can be used as well
  if( key in cache ) {
    return cache[key];
  }else {
    cache[key] = componentA(props);
    return cache[key];
  }
}

そして、現時点で私が考えることができる純粋な機能コンポーネントの他の優れた特性があります。

  • ユニットテストフレンドリー
  • クラスベースのコンポーネントより軽量
  • それらは単なる関数であるため、再利用性が高い
于 2015-12-24T15:48:18.357 に答える
1

不必要な割り当ての回避

私の理解が正しければ、ステートレスな機能コンポーネントは通常のコンポーネントに変換されます。ソースから:

function StatelessComponent(Component) {
}
StatelessComponent.prototype.render = function() {
  var Component = ReactInstanceMap.get(this)._currentElement.type;
  return Component(this.props, this.context, this.updater);
};

ステートレス コンポーネントのインスタンスが作成されると、新しいオブジェクトが割り当てられます。この新しいオブジェクトには、 や などのライフサイクル メソッドがcomponentWillMountありcomponentWillReceivePropsます。これらのオブジェクトをまったく作成しない計画であると推測しています。オブジェクトを作成しないと、不要な割り当てが回避されます。

不必要なチェックの回避

ライフサイクル メソッドを実装するには、次のようないくつかのチェックが必要です。

if (inst.componentWillUpdate) {
  inst.componentWillUpdate(nextProps, nextState, nextContext);
}

ステートレスな機能コンポーネントには、これらのライフサイクル メソッドがないと見なすことができます。それはドキュメントが言及しているものかもしれませんが、私にはわかりません。

編集

質問に答えなかったり、うまく説明できなかったメモ化に関するものを削除しました。

于 2016-01-07T03:20:43.670 に答える