嵌套循环React组件与Flux,父级或子级的更改侦听器?

时间:2015-03-20 12:21:06

标签: javascript performance reactjs reactjs-flux

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

enter image description here

我的React组件及其来源:

  1. Gameboard
  2. TileColumn
  3. Tile
  4. 所有源代码can be viewed here


    它现在如何运作

    有一个GameStore,它包含一个二维javascript对象数组。对象具有'letter'字符串值和'active'布尔值。当用户单击一个字母时,会调度到GameStore,后者会更新该二维数组并发出Change事件。

    GameBoard组件侦听该更改事件,然后重新渲染10个TileColumns,每个TileColumns渲染10个Tiles。 GameBoard将商店的数据作为其状态的一部分,并且图块具有自己的字母/活动状态作为道具。

    问题是更改1个字母会导致重新渲染所有100个图块。


    shouldComponentUpdate

    我尝试在Tile上使用shouldComponentUpdate来指定它只应在其“active”值发生变化时才更新,但问题是this.props.active和nextProps.active都是相同的值:要么就是'两者都是假的,或两者都是真的。


    推迟对孩子的责任

    我的另一个想法是让每个Tile负责自己的更新,直接在tile上注册更改侦听器。我收到一个警告,我超过了监听器的数量,看起来好像100个更改监听器,所有触发每个字母更新的效率都会降低。虽然这只是Javascript,所以我们要避免一些DOM操作...


    性能

    我启动了Profiler,现在,在父母完成所有状态管理的情况下,它需要40ms才能在信件点击时重新渲染整个电路板。这还不错,但是当游戏变得更加复杂时,我担心它会变得明显延迟。


    需要帮助

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

    谢谢!

1 个答案:

答案 0 :(得分:12)

是的,这是默认情况下React为什么不快的典型例子。我有一个很长的例子here,确切地说你正在尝试解决什么样的问题。

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

  1. initialize the tiles on the board的方式很好,但modify the values for the tile只是改变对象的方式。这使得很难知道某个对象是否已经改变。

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

  3. 解决方案:

    使用shouldComponentUpdate(或只使用ReactComponentWithPureRenderMixin)以防止在Tile中浪费重新计算。当然,除非你做了很多事情,否则不会工作

    解决方案是:

    1. 您知道哪些属性可以变异,并根据这些属性设置shouldComponentUpdate
    2. 是否只允许更改tile.active?您可能只需define your callback,这样您只需检查prevProps.tile.active === this.props.tile.active的相等性。

      1. 创建一个新对象,以便轻松比较对象引用。
      2. 您可能已经知道var a = {}; var b = a会使a === b成为var c = {}; var d = {};,而c !== d会使mixins: [ReactComponentWithPureRenderMixin]成为{{1}}。每当您进行更新时都完全替换tile对象,以便您可以使用旧tile对象。这样,快速性能实际上只有{{1}}。

        这可能比你想要的更多垃圾,但它几乎是我如何在React中得到任何类型的集合。如果没有这些技术,我实际上无法在不停止工作的情况下使my crappy etch-a-sketch component工作。

        祝你好运!