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

Ric*_*oss 2 javascript reactjs react-jsx

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

请考虑以下组件布局

EventView
  EventViewSidebar
    EventViewList
      EventViewListRow
  EventViewDetail
Run Code Online (Sandbox Code Playgroud)

在此布局中,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>
    );
}
Run Code Online (Sandbox Code Playgroud)

这是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>
          );
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

为了更新单击EventViewDetaila的EventViewListRow时间,我在中定义了以下事件处理程序EventViewListRow

handleClick: function (event) {

    event.preventDefault();

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

},
Run Code Online (Sandbox Code Playgroud)

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

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

(客户端)<h3 data-reactid =".0">未选择任何内容

(服务器)<h3 data-reactid =".0.1.0">选择偶数

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

例如,最初我EventViewDetail直接调用了一个实例

          <div className="event-view__content col-md-8" id="eventDetail">
            <EventViewDetail />
          </div>
Run Code Online (Sandbox Code Playgroud)

但如果我只使用vanilla HTML,它也会挂起

          <div className="event-view__content col-md-8" id="eventDetail">
            <h3>Select an event to view</h3>
          </div>
Run Code Online (Sandbox Code Playgroud)

很明显我做错了什么,但我对React有点不熟悉所以我不知道那是什么.我读到我认为我在顶层EventView组件上有状态,但是我没有访问权限,而React似乎没有提供恢复组件链的能力.除非你应该将EventView实例作为属性传递给每个子组件?

哦,我还应该添加 - 我也尝试setStateEventViewListRow点击处理程序中删除调用,以防原因,但它没有任何效果.

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

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

Mar*_*ord 6

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