2

次のように React.js を使用してサイト全体を構築しています。

     React.render(
       <div id="mainWrapper">
         <MainHeader />
         <div id="contentWrapper" className="contentWrapper">
           <MainFlow data={example_data} />
           <AddElementWrapper data={activities} />
         </div>
       </div>,
       document.body
     );

しかし、データ保持コンポーネントの 1 つである MainFlow または AddElementWrapper で setProperties を呼び出すと、親を介してデータを操作する必要があることを示すエラーが表示されます。

Uncaught Error: Invariant Violation: replaceProps(...): You called `setProps` or `replaceProps` on a component with a parent. This is an anti-pattern since props will get reactively updated when rendered. Instead, change the owner's `render` method to pass the correct value as props to the component where it is created.

まず、これは、操作したいコンポーネントに別の所有者がいる場合にのみ問題になると思いました。ただし、私のコンポーネントには、所有者としての React コンポーネントがなく、としての HTML 要素だけがあります。

すべてのアプリケーション データを単一のルート コンポーネントに接続することで、この問題を回避できました。ただし、特定のデータ セットを個別に保持したいと考えています。方法はありますか?

4

3 に答える 3

2

Wrapper コンポーネントを定義し、そこでデータの状態を維持し、外部からデータが変更されたときに setState を呼び出すだけです。

Wrapper = React.createClass({
getInitialState: function() {
    return {example_data: example_data, activities: activities};
},
refresh: function() {
    this.setState({example_data: this.state.example_data, activities: this.state.activities});
},
render: function() {
    return (
        <div id="mainWrapper">
            <MainHeader/>
            <div id="contentWrapper" className="contentWrapper">
                <MainFlow data={this.state.example_data} />
                <AddElementWrapper data={this.state.activities} />
            </div>
        </div>
    );
  }
});

React.render(<Wrapper/>);
于 2014-11-20T19:59:26.003 に答える
1

アイデアは、データの変更を明示的にリッスンする React コンポーネントを持つことです。そのためには、コンポーネント マウントでコールバックをセットアップします。

Backbone+React (および BackboneReact mixin) または Flux+React の 2 つを探すことをお勧めします。

流動的な方法は、データの可用性に関するグローバル イベント システム (ディスパッチャー) を持つことであり、バックボーンの方法は、特定のコレクション イベントに登録することです。

このコードは、TodoMVC React-backbone プロジェクトの BackboneMixin から直接取得したものです。

componentDidMount: function() {
  // Whenever there may be a change in the Backbone data, trigger a
  // reconcile.
  this.getBackboneCollections().forEach(function(collection) {
    // explicitly bind `null` to `forceUpdate`, as it demands a callback and
    // React validates that it's a function. `collection` events passes
    // additional arguments that are not functions
    collection.on('add remove change', this.forceUpdate.bind(this, null));
  }, this);
},

もっと :

于 2015-02-03T16:55:58.760 に答える