Search code examples
reactjsbackbone.jsredux

Use Backbone View as React component


I have backbone control that I want to reuse in new module that would be written in React and Redux. I am very uncertain how to approach this. My initial idea is to wrap this backbone view in a react component. In a similar way I've done in sample project:

import React from 'react'
import ReactDOM from 'react-dom';
import Backbone from 'backbone';

var Test  = Backbone.View.extend({

render: function () {
    this.$el.html("<p> If you see that it's working</p>");
    return this;
}
});

class TestComponent extends React.Component {

  backboneComponent;

constructor(props) {
    super(props);
    this.backboneComponent = new Test();
}

render(){
    return (<div dangerouslySetInnerHTML={{__html:   this.backboneComponent.render().el.innerHTML}} ></div>);
}
}

ReactDOM.render( <div>
   <TestComponent/>
</div>
,document.getElementById("root"));

So this thing works but I have a second thoughts about it because of this dangerouslySetInnerHtml parameter. I am also not sure how I would resolve the problem with binding redux states with backbone models.

The other approach would be to throw the backbone view into global window object and than just interact with it from a React-Redux part of code. But I am not sure about that either. So people of the internet, do you have an answer for this burning question?


Solution

  • Another approach is to allow the React Component to render to the DOM, then render the Backbone element using the React Component's rendered DOM element.

    https://jsfiddle.net/x8wnb5r8/

    componentDidMount() {
      this.backboneComponent = new Test({
        el: ReactDOM.findDOMNode(this)
      }).render();    
    }
    

    What are the advantages?

    • Backbone doesn't enforce many rules when rendering, but it does expect to have a working DOM element at the core of any view, which can be interacted with during the lifecycle of the view. This approach maintains that.

    • This solution doesn't involve React's virtual DOM, which means the Backbone view can update without having to trigger any React functionality. Which should also perform better than a DOM->virtual DOM->DOM solution (as with innerHTML).

    • Backbone model events can still directly trigger view functionality, there is no need to have the model layers interact between Backbone and React

    The final code will need componentDidUpdate() and componentWillUnmount() handlers also.

    Here is a more elaborate version, showing state changes to both the React parent component (OtherReactContainer) and also Backbone view (BBView) updates: https://jsfiddle.net/w11Ly493/