32

ここ数週間、Facebook フレームワークの React.js と Backbone を一緒に使用してきましたが、Backbone コレクションに変更があった場合に React コンポーネントを再レンダリングする最も適切な方法が何であるかはまだ完全にはわかりません。 propとして渡されました。

現在私がしていることは、コレクションにリスナーcomponenentWillMountを設定しchange/add/remove、トリガー時に状態を設定することです。

componentWillMount: function(){
    var myCollection = this.props.myCollection;
    var updateState = function(){
        this.setState({myCollection: myCollection.models});
    }

    myCollections.on("add remove", updateState, this);
    updateState();
}

render: function(){
    var listItems = this.state.myCollection.map(function(item){
        return <li>{item.get("someAttr")}</li>;
    });
    return <ul>{listItems}</ul>;
}

モデルが状態に複製される例を見てきました:

var updateState = function () {
    this.setState({ myCollection: _.clone(this.myCollection.models) });
};

小道具のモデル/コレクションが状態を使用する代わりにレンダリングで直接使用され、コレクション/モデルが変更されたときに forceUpdate が呼び出され、コンポーネントが再レンダリングされるバリアントも見ました。

componentWillMount: function(){
    var myCollection = this.props.myCollection;
    myCollections.on("add remove", this.forceUpdate, this);
}

render: function(){
    var listItems = this.props.myCollection.map(function(item){
        return <li>{item.get("someAttr")}</li>;
    });
    return <ul>{listItems}</ul>;
}

さまざまなアプローチにはどのような利点と欠点がありますか? Reactの方法でそれを行う方法はありますか?

4

5 に答える 5

10

IMO、React はまだ非常に新しく、Backbone のようなデータとリアクティブ モデルの操作方法に関する確立されたルールはほとんどありません。これは、既存のアプリケーションがある場合の強みでもあります。react は、データ フロー全体を再定義することなく、アプリケーションの小さな部分に統合できます。

React はいつでも render "smart" を呼び出すことができるので、つまり、変更された部分のみを再レンダリングするだけなので、実際にはデータを状態として渡す必要はありません。データを渡し、最上位コンポーネントにリスナーを追加しforceUpdate、モデルが変更されたときに呼び出すだけで、うまく伝播します。

バックボーンモデルを状態ではなく小道具として渡す方が「正しい」ようです。

私が難しい方法で学んだ重要なことの 1 つは、バックボーン モデル リストをレンダリングするときにmodel.cid(ではなく) as キーを使用することです。Math.random()

var listItems = this.props.myCollection.map(function(item){
    return <li key={item.cid}>{item.get("someAttr")}</li>;
});

そうしないと、React はどのモデルを再レンダリングするかを認識できません。これは、すべてのモデルがレンダリングごとに新しいキーを持つためです。

于 2013-12-04T12:24:07.153 に答える
1

Eldar Djafarov の好意による別の BackboneMixin があります。これは、モデルが変更されたときにコンポーネントを再レンダリングし、双方向のデータバインディングを取得するための非常に便利な方法も提供します。

  var BackboneMixin = {
    /* Forces an update when the underlying Backbone model instance has
     * changed. Users will have to implement getBackboneModels().
     * Also requires that React is loaded with addons.
     */
    __syncedModels: [],
    componentDidMount: function() {
      // Whenever there may be a change in the Backbone data, trigger a reconcile.
      this.getBackboneModels().forEach(this.injectModel, this);
    },
    componentWillUnmount: function() {
      // Ensure that we clean up any dangling references when the component is
      // destroyed.
      this.__syncedModels.forEach(function(model) {
        model.off(null, model.__updater, this);
      }, this);
    },
    injectModel: function(model){
      if(!~this.__syncedModels.indexOf(model)){
        var updater = this.forceUpdate.bind(this, null);
        model.__updater = updater;
        model.on('add change remove', updater, this);
      }
    },
    bindTo: function(model, key){
      /* Allows for two-way databinding for Backbone models.
       * Use by passing it as a 'valueLink' property, e.g.:
       *   valueLink={this.bindTo(model, attribute)} */
      return {
        value: model.get(key),
        requestChange: function(value){
            model.set(key, value);
        }.bind(this)
      };
    }
  }

使用法を示す彼の jsFiddle は次のとおりです: http://jsfiddle.net/djkojb/qZf48/13/

于 2014-01-08T16:46:01.490 に答える
1

react.backboneは、React-Backbone 統合の最新のソリューションのようです。まだテストしていません。

于 2015-04-28T19:40:21.127 に答える