重新渲染一个ReactJS组件会挂起浏览器

Re-rendering a ReactJS component hangs browser

本文关键字:组件 ReactJS 挂起 浏览器 一个 新渲染      更新时间:2023-09-26

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

考虑下面的组件布局

EventView
  EventViewSidebar
    EventViewList
      EventViewListRow
  EventViewDetail

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

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

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>
          );
        }
    }
});
为了在单击EventViewListRow时更新EventViewDetail,我在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添加到EventView中定义的eventDetaildiv中,那么当我单击EventViewListRow中的链接时,控制台将显示以下消息,并且浏览器挂起。

警告:React试图在容器中重用标记,但校验和无效。这通常意味着您使用的是服务器呈现,而在服务器上生成的标记并不是客户机所期望的。React注入了新的标记来弥补它的工作,但你已经失去了许多服务器渲染的好处。相反,要弄清楚为什么在客户机或服务器上生成的标记不同:

(client)

没有选择

(server)

选择偶数

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

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

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

但是如果我使用普通的HTML

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

显然我做了一些非常错误的事情,但我有点不熟悉React,所以我不知道那是什么。我读到我应该在顶层EventView组件上有状态,但我没有访问权限,React似乎没有提供回到组件链的能力。除非你应该将EventView实例作为属性传递给每个子组件?

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

有谁能告诉我我做错了什么吗?EventView是否具有子组件的所有状态,如果是这样,我如何从嵌套的子组件引用父组件-我是否必须将EventView的实例作为prop传递给每个子组件?

抱歉,如果这些是白痴的问题!

你不应该调用React。在handleClick函数中渲染。就叫它。setState和React会自动重新渲染