Be the first user to complete this post

  • 0
Add to List

Using React with Backbone Models

React allows you to render views in a very high performance way. The best thing about react is that it also plays fair with other frameworks like backbone for implementing the other layers. For example, one of the simplest use case would be to use react's view components to render backbone models. NOTE: The entire source code of this project is available at github on the react-backbone-model branch of our react-webpack-setup project. If you are inclined to learn how to setup react with webpack you can checkout another article that covers the topic in detail. If it sounds complicated at first, its really not. If I were to sum it up one line, this is what I would say - Just call the component's forceUpdate() on the 'change' event in a backbone model. Lets put that line into some context and see how we can achieve that.
Since we are going to use the react-webpack-setup project, we will be conveniently using npm and require in our front end code.
Packages First lets install backbone model. We dont need the whole of backbone so we will just install the model package.
npm install backbone-model --save

The Model We will create a very simple backbone model called Note which contains a sigle attribute called details. models/Note.js
var Model = require('backbone-model').Model,
    Note = Model.extend({
      details: ""
    });

module.exports = Note;

The Components What follows next is the code for 2 react components. The first component Page is a top level page component that manages all the other components on the page. The second component Note is the component that will render our Note model. It simply displays a textarea called the 'editor' which, of course, you can edit. Upon editing, we want it to update the model's 'details' attribute. This value will be automatically displayed in another div on the page called as the 'viewer' and will be italicized. components/notes/Page.jsx
/**
 * @jsx React.DOM
 */

var React = require('react'),
    NoteModel = require('../../models/Note'),
    Note = require('./Note'),
    note = new NoteModel();

var Page = React.createClass({

    render: function() {

        return (
            <div>
                <Note model={note}/>
            </div>
        );

    }

});

module.exports = Page;

components/notes/Note.jsx
/**
 * @jsx React.DOM
 */

var React = require('react'),
    ModelUpdateMixin = require('../../mixins/ModelUpdateMixin');

var Note = React.createClass({

    mixins:[ModelUpdateMixin],

    render: function() {

        var p = this.props;

        return (
            <div>

                <div className="editor">
                    <h5>Notes Editor</h5>
                    <textarea rows="3" cols="50"
                        ref="noteDetails"
                        placeholder="Enter some notes"
                        onChange={this._onDetailChange}>
                        {p.model.get('details')}
                    </textarea>
                </div>

                <div className="viewer">
                    <h5>Viewer</h5>
                    <i>{p.model.get('details')}</i>
                </div>

            </div>
        );

    },

    _onDetailChange: function(e){
        var p = this.props,
            noteDetails = this.refs.noteDetails.getDOMNode().value;

        p.model.set('details', noteDetails);
    }

});

module.exports = Note;
The above code does two simple things, it renders the detail attribute of the model once in a textarea and once in a div. The textarea can be edited. We listen to the onChange event and simply set the value on the model equal to the value on the textfield. Normally this would not let you edit the textfield. The reason why you can edit the textfield is because of the Mixin that is defined at the top of this class at the lines that read mixins:[ModelUpdateMixin].
The Mixin This is the glue object that causes the view to update when the model updates. React lets you define mixins that allow you to augment a component's lifecycle methods. A mixin that then be used in a react component, as seen in the code for Note.jsx above. What you see below is the ModelUpdateMixin, which is nothing but an object that augments two of React's component's lifecycle methods to whichever component it is included- the componentWillMount and the componentWillUnmount. The code below is pretty simple - on component mount, just subscribe to the component's model's change event and force a re-render of the view when a change is triggered by the model. You could add safety checks in your own code just in case model is undefined, but for the sake of this example, this should suffice. On component unmount, simply unsubscribe from the change event. ModelUpdateMixin.js
var ModelUpdateMixin = {

    componentWillMount: function(){
        this.props.model.on("change", (function() {
          this.forceUpdate();
        }.bind(this)));
    },

    componentWillUnmount: function(){
        this.props.model.off("change");
    }

};

module.exports = ModelUpdateMixin;

That said, you are now ready for showtime. To see the working example for yourself, download the branch - react-backbone-model from our repository and run the following commands on your terminal.
sudo npm install -g grunt-cli
npm install
npm run dev

Then open localhost:3000/notes.html in your browser and have some fun.




Also Read:

  1. imperative vs declarative/functional programming
  2. Pass props to the handler component in react-router
  3. Reactjs flux architecture - Visualized
  4. Passing the store down implicitly via context in a react redux app
  5. Pass down props using React childContextTypes in a deeply nested component tree