Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stuffing React component in Backbone view

I am getting a React error:

Error: Invariant Violation: _registerComponent(...): Target container is not a DOM element.

I think I know what the problem is but I don't know how to solve it. The problem is that I want to reference a div element id in the render function, but the html in the render function has not been rendered to the DOM yet by the time I want to stick something into that html. So my question is - how can I reference an element id of the html from my render function before it is rendered to the DOM? this has become what I think to be a jQuery question.

Here's the code in the render function of a simple Backbone.View:

     var self = this;

     var ret = EJS.render(template, {});

     this.$el.html(ret); //nice, but hasn't been rendered to the DOM yet

     React.render(
        <TimerExample start={Date.now()} />,
         self.el    //this works no problemo
    );

     React.render(
       <MenuExample items={ ['Home', 'Services', 'About', 'Contact us'] } />,
       $('#react-menu-example-div-id')[0]  //this is *not* working, what is the right call here, so that this view can coexist with the above React view?
     );

the first React.render call works if it is by itself. But the second React.render doesn't work and is the one throwing the error.

My template just looks like this:

<div>
    <div id="react-menu-example-div-id">menu example goes here</div>
</div>

my Backbone.View in question is creating its own el. What I am trying to do might be completely whack - I just want to render two separate/unrelated/different React components in the same Backbone view. Is there a good pattern for this?

like image 747
Alexander Mills Avatar asked Jul 02 '26 19:07

Alexander Mills


2 Answers

Your first render statement into self.el is replacing the contents of the DOM for that element. So by the time your second render call is made the #react-menu-example div no longer exists. You can fix this by just rendering to another element inside the parent. Although in general I think it would be best to have as much of your templating/rendering in React and not use the backbone view for too much of the templating.

Here is an example of rendering to two different ids inside the same backbone view

https://jsfiddle.net/sa4vvtjL/2/

Template

<div id="search_container">a</div>

<script type="text/template" id="search_template">
    <div>
        <div id="placeholder1"></div>
        <div id="react-menu-example-div-id"></div>
    </div>
</script>

JS

var Hello = React.createClass({
    render: function(){
        return (<div> {this.props.start} </div>)
    }
});

var Hello2 = React.createClass({
    render: function(){
        return (<div> lala </div>)
    }
});

var SearchView = Backbone.View.extend({
    initialize: function () {
        this.render();
    },
    render: function () {
        var template = _.template($("#search_template").html(), {});
        this.$el.html(template);

        React.render(
            <Hello start={Date.now()} />,
            $('#placeholder1')[0] 
        );

        React.render(
            <Hello2  />,
            $('#react-menu-example-div-id')[0] 
        );

    }
});

var search_view = new SearchView({
    el: $("#search_container")
});
like image 174
noveyak Avatar answered Jul 04 '26 09:07

noveyak


What is actually says it's that element with id 'react-menu-example-div-id' is not on the page yet.

I can observe you are using jquery, so why not:

$(document).ready(function() {
React.render(
       <MenuExample items={ ['Home', 'Services', 'About', 'Contact us'] } />,
       $('#react-menu-example-div-id')[0]
     );
});
like image 42
gor181 Avatar answered Jul 04 '26 08:07

gor181



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!