Open iamdanfox opened 10 years ago
Could you show a piece of code where you do this? I think it would be good to bind to the result of a function, instead of to a string referring to a property. Problem is, if it just occurs sometimes in a function, it is hard to guess the lifecycle beforehand; should it unbind on props updating? On state changing? etc.
I can't paste the code here, but I was writing a FilteredSearchComponent
that received a search string and displayed a filtered subset of results. Each result was represented as a backbone model. They were loaded from the server and would magically update with push updates.
In my scenario, I needed the FilteredSearchComponent
to re-render if any of the result models changed (because that might change whether they passed the filter).
I did the unbinding at the componentWillUnmount
stage since a few unnecessary render
calls work fine with React :)
Was there a specific reason you were enable to bind on 'change' of the collection?
That would work perfectly if the result models were returned in a collection (and some logic was moved out of the component). Unfortunately, that isn't always possible, because those resultModels
might then end up appearing in multiple collections, which doesn't have great support as far as I can tell...
In all honesty, I think this is quite a small issue, but might be an interesting consideration for future development / refactoring.
I paraphrased the component code below (compiled js also available)...
FilteredSearchComponent = React.createClass
propTypes:
filterString: React.PropTypes.string.isRequired
getInitialState: ->
loading: true
results: []
componentWillMount: ->
listOfModels = App.dataLayer.checkOutAllPushModels()
for model in listOfModels # would like to get rid of this... listen to all and autounbind
model.on 'change', (=>@forceUpdate()), @
@setState
loading: false
results: listOfModels
componentWillUnMount: ->
for model in @state.results
App.dataLayer.returnPushModel model
model.off 'all', null, @ # would like to get rid of this too
render: ->
matchesFilterString = (model) ->
return model.matchesFilterString(@props.filterString)
<div>
{ if @state.loading
<Spinner />
else
@state.resultModels.filter(matchesFilterString).map (model) ->
<ResultRow model={model} /> }
</div>
Components often need to react to Backbone models that are introduced during the component's lifecycle. (e.g. a model returned by a function that is stored in this.state).
At present, I just inline the crucial bits from your
subscribe
andunsubscribe
functions. It would be really cool if there was a way to dynamically add another React mixin or somehow 'subscribe' to these models without needing to rewrite it each time