当一个项目发生变化时,React 会重新呈现整个列表

React re-renders entire list when one item is changed

我有一个简单的 React 应用程序,可以呈现 5000 种产品的名称和价格。价格是可编辑的,更改后价格会反映在状态中。

https://github.com/TonyCaffer/thinking-in-react-1

App.js 通过 onChangePrice 函数管理状态并处理价格变化,该函数向下传递给 ProductTable 和每个 ProductRow

我使用 immutability-helpers,我专门只更改已更改产品的状态记录。

但是每次更改都会有明显的一秒延迟,因为 React 正在重新渲染所有产品。每个产品都有一个键 属性,我认为它可以帮助 React 只重新渲染必要的组件。

在生产版本中,它不那么卡顿,但所有产品都会重新渲染,这是我试图解决的根本问题。

为什么要重新呈现所有产品组件?是因为我通过高级 ProductTable 传递 this.state.products 从而触发了列表的完全重绘吗?如果是这样,当状态在列表中时,每个 ProductRow 如何管理自己的记录状态?

React 分两个阶段安排更新:协调器阶段(或渲染阶段,因为它涉及我们定义的组件的渲染方法)和提交阶段。当状态更新时,React 无论如何都会启动更新过程。使用适当的 shouldComponentUpdate 可以帮助您减少子组件的更新次数

可能的解决方案:对 ProductRow 使用 shouldComponentUpdate,如下所示:

shouldComponentUpdate(nextProps) {
  if (
    this.props.guid !== nextProps.guid
    || // similarly check if the other new props are different
  ) {
    return true;
  }
  return false
}

以上检查将确保当父级检测到 setState 并在新的 React Fiber 的工作循环中安排更新时,不会对子组件进行重新计算并且提交阶段完全跳过任何 DOM 更新。

Lin Clark explains the two phases真不错。它肯定会帮助您了解 React Fiber 如何管理更新。

您可以研究 React Virtualised 以改善极长列表的感知性能。