handling backbone model/collection changes in react.js
backbone.js, javascript, reactjs
Solution
Instead of manually binding event listeners, you can use a mixin based on this BackboneMixin to help automatically bind and unbind the listeners:
https://github.com/facebook/react/blob/1be9a9e/examples/todomvc-backbone/js/app.js#L148-L171
Then you simply write
var List = React.createClass({
mixins: [BackboneMixin],
getBackboneModels: function() {
return [this.props.myCollection];
},
render: function(){
var listItems = this.props.myCollection.map(function(item){
return <li>{item.get("someAttr")}</li>;
});
return <ul>{listItems}</ul>;
}
});
and the component will be rerendered when anything changes in the collection. You only need to put BackboneMixin on the top-level component -- any descendants will be rerendered automatically at the same time.
Problem
I've been working with facebooks framework React.js together with Backbone for the last couple of weeks and I'm still not entirely sure what is the most appropriate way to re-render a React component when there are changes in a Backbone collection that has been passed in as a prop. currently what I do is in `componenentWillMount` I set up `change/add/remove` listeners on the collection and set state when it triggers: ``` 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>; } ``` I have seen examples where the models are cloned to the state: ``` var updateState = function () { this.setState({ myCollection: _.clone(this.myCollection.models) }); }; ``` I've also seen variants where model/collection in props is used directly in render instead of using state, and then forceUpdate is called when the collections/model changes, causing the component to re-render ``` 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>; } ``` what benefits and drawbacks are there to the different approaches? Is there a way of doing it that is The React way?