web-dev-qa-db-ja.com

すべての推移的に到達可能な状態を含む反応コンポーネントをリセットするにはどうすればよいですか?

リセットしたい概念的にステートフルなコンポーネントが反応することがあります。理想的な動作は、古いコンポーネントを削除し、新しい元のコンポーネントを再読み込みすることと同等です。

Reactには、コンポーネントの明示的な状態を設定できるsetStateメソッドが用意されていますが、ブラウザーのフォーカスやフォームの状態などの暗黙的な状態は除外され、子の状態も除外されます。間接的な状態をすべて捕捉するのは難しい作業になる可能性があり、驚くべき状態のすべての新しいビットでモグラを叩くよりも、厳密かつ完全に解決したいと思います。

これを行うためのAPIまたはパターンはありますか?

Edit:this.replaceState(this.getInitialState())アプローチを示し、this.setState(this.getInitialState())アプローチと対比する簡単な例を作成しました: jsfiddle -replaceStateはより堅牢です。

80
Eamon Nerbonne

言及した暗黙的なブラウザの状態と子の状態が確実にリセットされるようにするには、keyによって返されるルートレベルコンポーネントに render属性 を追加します。変更されると、そのコンポーネントは破棄され、ゼロから作成されます。

render: function() {
    // ...
    return <div key={uniqueId}>
        {children}
    </div>;
}

個々のコンポーネントのローカル状態をリセットするショートカットはありません。

181
Sophie Alpert

実際にはreplaceStateを避け、代わりにsetStateを使用する必要があります。

ドキュメントでは、replaceState "Reactの将来のバージョンで完全に削除される可能性がある"と述べています。 replaceStateはReactの哲学とはまったく違うので、間違いなく削除されると思います。 Reactコンポーネントがスイスのナイフのように感じられるようにします。これは、Reactコンポーネントの自然な成長に対抗し、小さくなり、より目的に合わせて作成されます。

Reactで、一般化または専門化について誤解する必要がある場合:専門化を目指します。結果として、コンポーネントの状態ツリーには特定の節約が必要です(ただし、ブランドにまたがる新製品を足場にしている場合は、この規則を上手に破ることは問題ありません)。

とにかくこれがあなたのやり方です。上記のBenの(受け入れられた)答えに似ていますが、次のようになります。

this.setState(this.getInitialState());

また(Benも言ったように)「ブラウザの状態」をリセットするには、そのDOMノードを削除する必要があります。 vdomのパワーを活用し、そのコンポーネントに新しいkeyプロップを使用します。新しいレンダリングは、そのコンポーネントの卸売を置き換えます。

リファレンス: https://facebook.github.io/react/docs/component-api.html#replacestate

15
williamle8300

再初期化する必要がある要素にkey属性を追加すると、propsまたはstateが要素に関連付けられるたびに、属性が再ロードされます。

key = {new Date()。getTime()}

以下に例を示します。

render() {
  const items = (this.props.resources) || [];
  const totalNumberOfItems = (this.props.resources.noOfItems) || 0;

  return (
    <div className="items-container">
      <PaginationContainer
        key={new Date().getTime()}
        totalNumberOfItems={totalNumberOfItems}
        items={items}
        onPageChange={this.onPageChange}
      />
    </div>
  );
}
4
jsbisht