【问题标题】:Stuffing React component in Backbone view在 Backbone 视图中填充 React 组件
【发布时间】:2015-10-11 18:24:35
【问题描述】:

我收到一个 React 错误:

错误:不变违规:_registerComponent(...):目标容器 不是 DOM 元素。

我想我知道问题出在哪里,但我不知道如何解决它。问题是我想在渲染函数中引用一个 div 元素 id,但是当我想在那个 html 中粘贴一些东西时,渲染函数中的 html 还没有被渲染到 DOM。所以我的问题是 - 在渲染到 DOM 之前,如何从渲染函数中引用 html 的元素 ID?这已成为我认为的 jQuery 问题。

这是一个简单 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?
     );

第一个React.render 调用如果它本身就可以工作。但是第二个 React.render 不起作用并且是抛出错误的那个。

我的模板看起来像这样:

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

我的 Backbone.View 正在创建自己的 el。我想要做的可能是完全重击 - 我只想在同一个 Backbone 视图中呈现两个单独/不相关/不同的 React 组件。这有什么好的模式吗?

【问题讨论】:

  • 你不能$(self.el).find('#react-menu-example-div-id')[0]吗?
  • 也许吧。明天试试。 jquery find 函数可以搜索不在 DOM 中的 HTML 吗?
  • 虽然 jQuery 确实如此,但它仍然无法正常工作,正如 noveyak 在下面的答案中解释的那样。
  • @HannesJohansson 是的,谢谢。 jQuery 的 find() 函数似乎能够找到尚未在 DOM 中的 HTML 元素,我认为确实非常方便

标签: javascript jquery backbone.js reactjs


【解决方案1】:

您在 self.el 中的第一个渲染语句是替换该元素的 DOM 内容。因此,当您进行第二次渲染调用时,#react-menu-example div 不再存在。您可以通过仅渲染到父级内的另一个元素来解决此问题。虽然总的来说,我认为最好在 React 中拥有尽可能多的模板/渲染,并且不要将主干视图用于太多的模板。

这是一个在同一个主干视图中渲染到两个不同 id 的示例

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

模板

<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")
});

【讨论】:

  • 我其实觉得你需要使用jQuery的find()函数,像这样:$(this.el).find('#placeholder1')[0],我不这么认为将按原样工作,因为模板还没有在 DOM 中,并且 $('#age') 只会在真实的 DOM 中查找,你能确认吗?
  • 查看此问答以获取更多信息stackoverflow.com/questions/31547521/…
  • this.$el.html(template) 我相信将它放在 dom 中。检查我的 JSfiddle,您可以看到 2 个反应视图在不同的附加点呈现。
  • 啊,是的,它会将它放在 DOM 中,因为您在 new SearchView({el:...}) 中传递了 el...但是,如果您有兴趣学习新知识,请单击链接上面的 jQuery.find() 可以如何帮助你,如果你的父视图创建自己的不存在的 el
【解决方案2】:

实际上是 id 为“react-menu-example-div-id”的元素尚未出现在页面上。

我可以观察到您正在使用 jquery,所以为什么不呢:

$(document).ready(function() {
React.render(
       <MenuExample items={ ['Home', 'Services', 'About', 'Contact us'] } />,
       $('#react-menu-example-div-id')[0]
     );
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    相关资源
    最近更新 更多