重新呈现ReactJS组件会挂起浏览器

时间:2015-07-21 18:33:47

标签: javascript reactjs react-jsx

我一直在尝试使用ReactJS创建基于组件的UI,而不是我通常使用的百万全局函数,变量和不可重用标记的slapdash方法。到目前为止,我真的很喜欢React,但我遇到了绊脚石。

考虑以下组件布局

EventView
  EventViewSidebar
    EventViewList
      EventViewListRow
  EventViewDetail

在此布局中,每个唯一键都会出现多次EventViewListRow次。单击EventViewListRow的实例应更新EventViewDetail以及该项目的详细信息。

这是顶级render组件的EventView函数:

render: function () {
    return (
      <div className="event-view row-fluid">

          <div className="event-view__sidebar col-md-4">
            <EventViewSidebar projectId={this.state.projectId} />
          </div>

          <div className="event-view__content col-md-8" id="eventDetail">

          </div>

      </div>
    );
}

这是EventViewDetail组件

var EventViewDetail = React.createClass({

    getInitialState: function () {
        return { eventId: 0 };
    },

    render: function () {
        if (this.state.eventId === 0) {
            return (<h3>Nothing selected</h3>);
        }
        else {
            return (
          <div>
              {this.state.eventId}
          </div>
          );
        }
    }
});

为了在点击EventViewDetail时更新EventViewListRow,我在EventViewListRow

中定义了以下事件处理程序
handleClick: function (event) {

    event.preventDefault();

    React.render(
            React.createElement(EventViewDetail, { eventId: this.props.id }),
              document.getElementById("eventDetail")
            ).setState({ eventId: this.props.id });

},

这一切似乎都运行正常(除了上面的setState调用,我必须添加,否则点击其他EventViewListRow似乎没有任何效果 - 毫无疑问这是我的第一个问题)。实际的关键问题是,如果我将默认html添加到eventDetail中定义的EventView div,那么当我单击EventViewListRow中的链接时,控制台和浏览器中会显示以下消息挂起。

  

警告:React尝试在容器中重用标记,但校验和无效。这通常意味着您正在使用服务器呈现,并且在服务器上生成的标记不是客户端所期望的。 React注入了新的标记以补偿哪些有效但你已经失去了服务器渲染的许多好处。相反,弄清楚为什么生成的标记在客户端或服务器上是不同的:

     

(客户)&lt; h3 data-reactid =&#34; .0&#34;&gt;没有选择      

(服务器)&lt; h3 data-reactid =&#34; .0.1.0&#34;&gt;选择偶数

一旦浏览器标签(Chrome 43)挂起,我就必须使用任务管理器终止它。

最初,我直接调用EventViewDetail的实例,例如

          <div className="event-view__content col-md-8" id="eventDetail">
            <EventViewDetail />
          </div>

但如果我只使用vanilla HTML

,它也会挂起
          <div className="event-view__content col-md-8" id="eventDetail">
            <h3>Select an event to view</h3>
          </div>

显然我做错了什么,但我对React有点不熟悉,所以我不知道那是什么。我读到我认为我在顶级EventView组件上有状态,但我无法访问它,而React似乎无法提供恢复功能组件链。除非您应该将EventView实例作为属性传递给每个子组件?

哦,我还应该添加 - 我也尝试从setState点击处理程序中移除EventViewListRow调用,以防原因,但它没有效果。

任何人都可以就我做错了什么提出任何建议。 EventView应该具有子组件的所有状态,如果是,我如何从嵌套子组件引用父组件 - 我是否必须将EventView的实例作为支柱传递给每个组件子?

对不起,如果这些都是白痴问题!

1 个答案:

答案 0 :(得分:6)

您不应该在handleClick函数中调用React.render。只需调用this.setState,React将自动再次渲染。