Nested-loop React components with Flux, change-listeners on parent or children?

Nested-loop React components with Flux, change-listeners on parent or children?

我正在 React/Flux 中构建一个 Word Dojo 克隆。该游戏本质上是 Boggle - 您可以通过单击网格中相邻的字母来拼词:

我的 React 组件及其来源:

  1. Gameboard
  2. TileColumn
  3. Tile

全部源代码can be viewed here.


目前的工作情况:

有一个 GameStore 包含 two-dimensional 个 javascript objects 数组。 objects 有一个 'letter' 字符串值和一个 'active' 布尔值。当用户单击一个字母时,它会发送到 GameStore,GameStore 会更新 two-dimentional 数组并发出 Change 事件。

GameBoard 组件侦听该更改事件,然后 re-renders 10 个 TileColumns,每个 TileColumns 依次呈现 10 个 Tiles。 GameBoard 将商店的数据作为其状态的一部分,而图块将自己的 letter/active 状态作为道具。

问题是更改 1 个字母会导致所有 100 个图块都变成 re-rendered。


shouldComponentUpdate

我尝试在 Tile 上使用 shouldComponentUpdate 来指定它应该只在其 'active' 值发生变化时更新,但问题是 this.props.active 和 nextProps.active 始终是相同的值:它们要么都为假,要么都为真。


将责任推给 children

我的另一个想法是让每个 Tile 负责自己的更新,方法是直接在 tiles 上注册更改侦听器。我收到一条警告,说我超过了听众的数量,而且似乎 100 个更改听众都在每次字母更新时都触发,效率会降低。尽管这只是 Javascript,所以我们会避免一些 DOM 操纵...


性能

我启动了 Profiler,现在,parent 完成了所有的状态管理,re-render 整个板子点击字母需要 40 毫秒。这还不错,但是当游戏变得更复杂时,我担心它会变得明显延迟。


需要帮助

具体来说,我正在寻找有关这种情况下最佳实践的建议(当你有嵌套的、迭代的组件时),如果 shouldComponentUpdate 解决方案,但我只是在使用错了。

谢谢!

是的,这是为什么默认情况下 React 速度不快的经典示例。我有一个很长的示例 here 可以准确说明您要解决的问题类型。

基本上你有两个典型的问题:

  1. initialize the tiles on the board is fine, but the way you modify the values for the tile 的方式只是改变对象。这使得很难知道某个对象是否发生了变化。

  2. 默认情况下,React 天真地重新计算整个应用程序。如果您智能地使用 shouldComponentUpdate,则只能防止使用 render() 对元素进行昂贵的重新计算。

解决方案:

使用 shouldComponentUpdate(或仅使用 ReactComponentWithPureRenderMixin)以防止在 Tile 中进行无用的重新计算。当然,这个 不会起作用 除非你做一些事情。

解决方案是:

  1. 您知道允许更改哪些属性并根据这些设置 shouldComponentUpdate

只能改tile.active吗?您也许可以 define your callback 这样您就可以只检查 prevProps.tile.active === this.props.tile.active.

是否相等
  1. 创建一个新对象,以便轻松比较对象引用。

您可能已经知道 var a = {}; var b = a 将达到 a === b,并且 var c = {}; var d = {}; 将达到 c !== d。每当您进行更新时完全替换 tile 对象,以便您可以在旧对象所在的位置使用新的 tile 对象。这样,快速性能实际上只差 mixins: [ReactComponentWithPureRenderMixin]

这可能比您想要的更废话,但这几乎就是我如何让任何类型的集合在 React 中很好地呈现。如果没有这些技巧,我真的无法 my crappy etch-a-sketch component 不停地工作。

祝你好运!