clayallsopp / react.backbone

Plugin for React to make Backbone migration easier
MIT License
839 stars 60 forks source link

Multiple models #11

Closed markijbema closed 10 years ago

markijbema commented 10 years ago

I wanted to start the discussion a bit on what should happen when we have a component which has to listen to multiple models. I've had the same pain in Marionette, but there it was harder to get out of this. However, in react there is little reason to support only one model. If you disregard the createBackboneClass for a moment, and look only at the mixin, there is little reason it couldn't be parameterized on what field the model is in, so for instance:

 React.BackboneMixin = function(field) { return {
  ...
  componentDidMount: function() {
    // Whenever there may be a change in the Backbone data, trigger a reconcile.
    this._subscribe(this.props[field]);
  },
  ...
}}

I've actually found a project which does something similar: https://github.com/magalhas/backbone-react-component

I like this project conceptually better though, because it's simpler, and doesn't try to let a react component immitate a backbone view. I really like the simplicity, but think it's a bit too simple if it only allows for one model.

So I was wondering if you would be open towards allowing multiple models.

My proposal would be to make the mixin parameterized, let the createBackboneClass use the parameterized mixin, with 'model' as parameter. This way, people using createBackboneClass wouldn't notice the difference, and you can get extra flexibility using the mixin.

clayallsopp commented 10 years ago

That's an interesting idea, and I think it makes sense.

Have any strong opinions about other possible implementations, instead of a parameterized mixin?

Also, will React do the right backwards-compatible thing if React.BackboneMixin is a function instead of an object? (i.e. does it act like _.result(mixin))

markijbema commented 10 years ago

I have some medium-strong opinions about the alternatives ;) I dislike namespacing it. I don't like the polish-notation like 'model'/'model' everywhere. I'd like to be able to call my user a user, without explicitly saying 'model' somewhere. That would be the reason why I dislike 1 and 3.

And option 2 wouldn't work for me, since I'd like to pass through models. So componentA contains componentB. ComponentB needs 'user', componentA gets user passed in, and passes it through to componentB. With solution 2 componentA would get rerendered, while only rerenderingB would be necessary. In practice, in our app this would mean that certain updates would rerender the whole tree, while only a small subcomponent changes.