Skip to content

Instantly share code, notes, and snippets.

@BinaryMuse
Last active February 1, 2017 00:51
Show Gist options
  • Star 34 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save BinaryMuse/334120e0ef156e410f98 to your computer and use it in GitHub Desktop.
Save BinaryMuse/334120e0ef156e410f98 to your computer and use it in GitHub Desktop.
Integrating React with Marionette

Integrating React with Marionette

See ReactComponentView and BackboneModelWatchMixin, below.

Notes

The BackboneModelWatchView could use some additional methods to allow adding/removing watched models after the component is created.

Example

// marionette_ticket_view.js

var Marionette = require("marionette"),
    ReactComponentView = require("./mixins/react_component_view"),
    TicketViewComponent = require("./ticket_view_component");

module.exports = Marionette.View.extend(ReactComponentView).extend({
  initialize: function(options) {
    this.ticket = options.model;
  },

  getReactComponent: function() {
    return TicketViewComponent({ticket: this.ticket});
  }
});

// ticket_view_component.js

var React = require("react"),
    BackboneModelWatchMixin = require("./mixins/backbone_model_watch_mixin"),
    Ticket = require("./models/ticket");

var MyReactComponent = React.createClass({
  mixins: [BackboneModelWatchMixin],

  propTypes: {
    ticket: React.PropTypes.instanceOf(Ticket).isRequired
  },

  getBackboneModels: function() {
    return [this.props.ticket, this.props.ticket.get("comments")];
  },

  render: function() {
    if (this.props.ticket.isComplete()) {
      return <div>...</div>;
    } else {
      return <div onClick={this.completeTicket}>...</div>;
    }
  },

  completeTicket: function() {
    this.props.ticket.complete();
  }
});

module.exports = MyReactComponent;
/**
* Automatically re-render a React component when one or more backbone
* models emit any events. Automatically binds and unbinds during the normal
* React component lifecycle hooks.
*
* React.createClass({
* mixins: [BackboneModelWatchMixin],
*
* getBackboneModels: function() {
* return [this.props.model, someOtherModel];
* }
* });
*
*/
var _ = require("underscore");
module.exports = {
componentDidMount: function() {
this._watchedBackboneModels = this.getBackboneModels();
_.each(this._watchedBackboneModels, function(model) {
model.on("all", this._doBackboneUpdate);
}, this);
},
componentWillUnmount: function() {
_.each(this._watchedBackboneModels, function(model) {
model.off("all", this._doBackboneUpdate);
}, this);
},
_doBackboneUpdate: function() {
if (this.isMounted()) this.forceUpdate();
},
};
/**
* Easily create a Marionette view that contains a React component and mount/unmount
* it as appropriate in `onShow`/`onClose`.
*
* Marionette.View.extend(ReactComponentView).extend({
* initialize: function(options) {
* this.model = options.model;
* },
*
* getReactComponent: function() {
* return SomeComponent({model: this.model});
* }
* });
*
*/
var React = require("react");
module.exports = {
onShow: function() {
if (this._reactMountEl) {
React.unmountComponentAtNode(this._reactMountEl);
}
this._reactMountEl = this.$el[0];
var component = this.getReactComponent();
React.renderComponent(component, this._reactMountEl);
},
onClose: function() {
if (this._reactMountEl) {
React.unmountComponentAtNode(this._reactMountEl);
}
}
};
@przeor
Copy link

przeor commented Sep 1, 2016

Hi I see that you use React, so I am sure that you will find interesting the https://reactjs.co - this is the free online convention and tutorial book for React.JS Developers. React is not only the View (in MVC) anymore. ReactJS For Dummies: Why & How to Learn React Redux, the Right Way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment