Be the first user to complete this post
|
Add to List |
Using React with Backbone Models
Then open
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;
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
localhost:3000/notes.html
in your browser and have some fun.
Also Read:
- Uncaught TypeError: Cannot read property 'toUpperCase' of undefined in React
- Passing the store down implicitly via context in a react redux app
- imperative vs declarative/functional programming
- Pass props to the handler component in react-router