Connect Backbone Models and Collections to React.
Usage
npm install connect-backbone-to-react
or yarn add connect-backbone-to-react
in your React/Backbone project. See code samples below to how to integrate into your code.
Example
connectBackboneToReact
const UserModel = Backbone.Model.extend();
const UserCollection = Backbone.Collection.extend({ model: UserModel });
const userInstance = new UserModel({ name: "Harry", laughs: true });
const anotherUserInstance = new UserModel({ name: "Samantha", laughs: false });
const userCollection = new UserCollection([userInstance, anotherUserInstance]);
class MyComponent extends React.Component {
render() {
return (
<div>
<p>My user laughs: {this.props.doesUserLaugh ? "yes" : "no"}</p>
<button
onClick={() => this.props.setUserLaughs(!this.props.doesUserLaugh)}
>
Toggle Laughing User
</button>
<h4>All Users</h4>
<ul>
{this.props.users.map(user => (
<li key={user.name}>{user.name}</li>
))}
</ul>
</div>
);
}
}
// Maps Models to properties to give to the React Component. Optional.
// Default behavior is to call `.toJSON()` on every Model and Collection.
// Second argument are props given to the React Component.
const mapModelsToProps = (models, props) => {
const { user, allUsers } = models;
const { showOnlyLaughingUsers } = props;
// Everything returned from this function will be given as a prop to your Component.
return {
doesUserLaugh: user.get("laughs"),
users: showOnlyLaughingUsers
? allUsers.toJSON().filter(user => user.laughs === true)
: allUsers.toJSON(),
setUserLaughs(newVal) {
user.set("laughs", newVal);
}
};
};
// Options.
const options = {
// Should our event handler function be wrapped in a debounce function
// to prevent many re-renders.
debounce: false, // or `true`, or a number that will be used in the debounce function.
// Define what events you want to listen to on your Backbone Model or Collection
// that will cause your React Component to re-render.
// By default it's ['all'] for every Model and Collection given.
events: {
user: ["change:name", "change:laughs"]
// You can disable listening to events by passing in `false` or an empty array.
},
// Define what modelTypes you expect to be contained on your `modelsMap` object.
// Useful for validating that you'll be given what model type you expect.
// Uses instanceof, and throws an error if instanceof returns false.
// By default no modelTypes are defined.
modelTypes: {
user: UserModel,
allUsers: UserCollection
},
// Enable access to the wrapped component's ref with the `withRef` option.
// You can then access the wrapped component from the connected component's `getWrappedInstance()`.
// This is similar to react-redux's connectAdvanced() HOC.
// By default, `withRef` is false.
withRef: true
};
const { connectBackboneToReact } = require("connect-backbone-to-react");
// Create our Connected Higher order Component (HOC).
const MyComponentConnected = connectBackboneToReact(
mapModelsToProps,
options
)(MyComponent);
Now that you've created your HOC you can use it!
// Map your Backbone Model and Collections to names that will be provided to
// your mapModelsToProps function.
const modelsMap = {
user: userInstance,
allUsers: userCollection
};
ReactDOM.render(
// Pass the modelsMap to the HOC via the models prop.
<MyComponentConnected models={modelsMap} showOnlyLaughingUsers={true} />,
document.getElementById("app")
);
BackboneProvider
Alternatively you might have a tree of connected Components. We shouldn't pass that modelsMap
object from one component to another. Instead we can take inspiration from react-redux's Provider component.
const { BackboneProvider } = require('connect-backbone-to-react');
const modelsMap = {
user: userInstance,
allUsers: userCollection,
},
ReactDOM.render(
// Pass the modelsMap to the BackboneProvider via the models prop.
// It will then get shared to every child connected component via React's context.
<BackboneProvider models={modelsMap}>
<MyComponentConnected>
<MyComponentConnected />
</MyComponentConnected>
</BackboneProvider>,
document.getElementById('app')
);
Rendering React Within Backbone.View
This library's focus is on sharing Backbone.Models with React Components. It is not concerned with how to render React Components within Backbone.Views. The React docs provide a possible implementation for this interopt.
Local development
To develop this library locally, run the following commands in the project root directory:
-
npm run watch
. The library will be automatically compiled in the background as you make changes. -
npm link
and then follow the instructions to use the local version of this library in another project that usesconnect-backbone-to-react
.
Run npm test
to run the unit tests.
Releasing a new version
- Make sure you have up to date
node_modules
before you proceed. Can be done vianpm ci
- Update the version via:
npm run release -- --release-as=major|minor|patch
- Optionally manually edit the revised
CHANGELOG.md
file. Commit changes. - Follow the directions from step 2: run
git push --follow-tags origin master; npm publish
to publish - Rejoice!
License
Apache 2.0