我正在React / Flux中构建一个Word Dojo克隆。游戏本质上是Boggle - 您可以通过单击网格中的相邻字母来创建单词:
我的React组件及其来源:
所有源代码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 解决方案,但我只是错误地使用它。
谢谢!
答案 0 :(得分:12)
是的,这是默认情况下React为什么不快的典型例子。我有一个很长的例子here,确切地说你正在尝试解决什么样的问题。
基本上你有两个典型的问题:
你initialize the tiles on the board的方式很好,但modify the values for the tile只是改变对象的方式。这使得很难知道某个对象是否已经改变。
默认情况下,React天真地重新计算整个应用程序。如果您智能地使用shouldComponentUpdate
,则只能使用render()来防止对元素进行昂贵的重新计算。
解决方案:
使用shouldComponentUpdate
(或只使用ReactComponentWithPureRenderMixin
)以防止在Tile
中浪费重新计算。当然,除非你做了很多事情,否则不会工作。
解决方案是:
shouldComponentUpdate
。是否只允许更改tile.active
?您可能只需define your callback,这样您只需检查prevProps.tile.active === this.props.tile.active
的相等性。
您可能已经知道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工作。
祝你好运!