Skip to content

Instantly share code, notes, and snippets.

@flenter
Created August 12, 2016 13:28
Show Gist options
  • Save flenter/9dd88b053be79468a87740954bf41171 to your computer and use it in GitHub Desktop.
Save flenter/9dd88b053be79468a87740954bf41171 to your computer and use it in GitHub Desktop.
Backbone-wrapper
/**
* A component to wrap/render backbone views. It will instantiate the backbone
* view with options as the main parameters.
*
* Usage:
* ```
* import AppSettings from 'modules/app-settings';
*
* const options = {};
*
* <Component
* options={options}
* View={AppSettings}
* />
* ```
*/
import merge from 'lodash.merge';
import React, { Component, PropTypes } from 'react';
class BackboneWrapper extends Component {
static propTypes = {
options: PropTypes.object,
View: PropTypes.func.isRequired,
};
static defaultProps = {
options: {},
};
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
if (this.element) {
this.createView();
}
}
componentDidUpdate() {
if (this.div && this.instance) {
// Checks if view has an updateOptions function and call it (With the options)
// if it returns true, the view can update itself without the need to recreate it
// on false: the view is recreated
if (this.instance.updateOptions) {
const options = this.getOptions(this.div);
if (this.instance.updateOptions(options)) {
// if true, then the backbone view has handled the changes correctly
return;
}
}
this.cleanupView();
}
this.createView();
}
componentWillUnmount() {
this.cleanupView();
}
getOptions() {
return merge(
{ el: this.div },
this.state || {},
this.props.options
);
}
instance = null;
div = null;
createView() {
this.div = document.createElement('div');
this.element.appendChild(this.div);
const options = this.getOptions();
this.instance = new this.props.View(options);
}
cleanupView() {
if (this.instance) {
this.instance.remove();
this.instance.unbind();
this.instance.$el.empty();
this.instance = null;
}
if (this.div) {
this.div = null;
}
}
registerElement = el => {
if (el && this.element && this.element !== el) {
/* eslint-disable no-console */
console.warn('backbone-wrapper::element/ref node changed.', el);
/* eslint-enable no-console */
}
this.element = el;
};
render() {
return <div ref={this.registerElement}></div>;
}
}
export default BackboneWrapper;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment