我正在 React/Flux 中构建一个 Word Dojo 克隆。该游戏本质上是 Boggle - 您可以通过点击网格中相邻的字母来拼词:
我的 React 组件及其来源:
所有源代码can be viewed here .
目前的运作方式:
有一个 GameStore包含 javascript 对象的二维数组。这些对象有一个“字母”字符串值和一个“事件” bool 值。当用户单击一个字母时,它会分派(dispatch)到 GameStore,GameStore 会更新该二维数组并发出 Change 事件。
GameBoard 组件监听该更改事件,然后重新呈现 10 个 TileColumns,每个 TileColumns 依次呈现 10 个 Tiles。 GameBoard 将商店的数据作为其状态的一部分,而图 block 将自己的字母/事件状态作为 Prop 。
问题是更改 1 个字母会导致重新渲染所有 100 个图 block 。
应该组件更新
我尝试在 Tile 上使用 shouldComponentUpdate 来指定它应该只在其“active”值发生变化时更新,但问题是 this.props.active 和 nextProps.active 始终是相同的值:要么它们'都是假的,或者都是真的。
将责任推给 child
我的另一个想法是让每个 Tile 负责自己的更新,方法是直接在 tiles 上注册更改监听器。我收到一条警告,说我超过了听众的数量,而且似乎 100 个更改听众都在每次字母更新时都触发,效率会降低。虽然这只是 Javascript,所以我们会避免一些 DOM 操作......
性能
我启动了 Profiler,现在,在父级执行所有状态管理的情况下,单击字母需要 40 毫秒才能重新渲染整个板。这还不错,但当游戏变得更加复杂时,我担心它会成为一个明显的延迟。
需要帮助
具体来说,我正在寻找有关这种情况下的最佳实践的建议(当你有嵌套、迭代的组件时),如果 shouldComponentUpdate 是解决方案,但我只是用错了。
谢谢!
最佳答案
是的,这是为什么默认情况下 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。每当您进行更新时完全替换 tile 对象,以便您可以在旧对象所在的位置使用新的 tile 对象。这样,快速的性能实际上只需要 mixins: [ReactComponentWithPureRenderMixin] 即可。
这可能比你想要的更废话,但这几乎是我如何让任何类型的集合在 React 中很好地呈现。没有这些技术,我真的无法获得 my crappy etch-a-sketch component不停地工作。
祝你好运!
关于javascript - 带有 Flux 的嵌套循环 React 组件,更改父级或子级的监听器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29166387/
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
我有一个名为posts的模型,它有很多附件。附件模型使用回形针。我制作了一个用于创建附件的独立模型,效果很好,这是此处说明的View(https://github.com/thoughtbot/paperclip):@attachment,:html=>{:multipart=>true}do|form|%>posts中的嵌套表单如下所示:prohibitedthispostfrombeingsaved:@attachment,:html=>{:multipart=>true}do|at_form|%>附件记录已创建,但它是空的。文件未上传。同时,帖子已成功创建...有什么想法吗?
我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle
使用rspec-rails3.0+,测试设置分为spec_helper和rails_helper我注意到生成的spec_helper不需要'rspec/rails'。这会导致zeus崩溃:spec_helper.rb:5:in`':undefinedmethod`configure'forRSpec:Module(NoMethodError)对thisissue最常见的回应是需要'rspec/rails'。但这是否会破坏仅使用spec_helper拆分rails规范和PORO规范的全部目的?或者这无关紧要,因为Zeus无论如何都会预加载Rails?我应该在我的spec_helper中做