Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 树结构的性能问题,应在React/Redux中更新组件_Reactjs_Redux_Immutable.js - Fatal编程技术网

Reactjs 树结构的性能问题,应在React/Redux中更新组件

Reactjs 树结构的性能问题,应在React/Redux中更新组件,reactjs,redux,immutable.js,Reactjs,Redux,Immutable.js,对于React、Redux和ImmutableJS,我是个新手,遇到了一些性能问题 我有一个大的数据树结构,目前我将其存储为此结构中的平面列表: new Map({ 1: new Node({ id: 1, text: 'Root', children: [2,3] }), 2: new Node({ id: 2, text: 'Child 1', children: [4] }), 3: new Node({ id:

对于React、Redux和ImmutableJS,我是个新手,遇到了一些性能问题

我有一个大的数据树结构,目前我将其存储为此结构中的平面列表:

new Map({
  1: new Node({
    id: 1,
    text: 'Root',
    children: [2,3]
  }),
  2: new Node({
    id: 2,
    text: 'Child 1',
    children: [4]
  }),
  3: new Node({
    id: 3,
    text: 'Child 2',
    children: []
  }),
  4: new Node({
    id: 4,
    text: 'Child of child 1',
    children: []
  })
});
虽然将其结构化为平面列表使更新节点变得容易,但我发现随着树的增长,交互变得缓慢。交互包括能够选择一个或多个节点、切换其子节点的可见性、更新文本等。看起来UI迟钝的一个关键原因是,每次交互都会重新绘制整个树


我想使用
shouldComponentUpdate
,这样如果我更新节点3,节点2和4就不会更新。如果数据存储为一棵树(我可以简单地检查是否
This.props!==nextrops
),那么这将很容易,但是由于数据存储在一个平面列表中,检查将非常复杂


我应该如何存储数据并使用
shouldComponentUpdate
(或其他方法)来支持具有数百或数千个树节点的平滑UI

编辑

我一直在顶层连接商店,然后必须将整个商店向下传递到子组件

我的结构是:

<NodeTree> 
  <NodeBranch>
    <Node>{{text}}</Node>
    <NodeTree>...</NodeTree>
  </NodeBranch>
  <NodeBranch>
    <Node>{{text}}</Node>
    <NodeTree>...</NodeTree>
  </NodeBranch>
  ...
</NodeTree>

{{text}}
...
{{text}}
...
...

可以使用
shouldComponentUpdate
进行简单检查,查看标题是否已更改,但鉴于树的递归性质,我没有类似的解决方案可用于

看起来最好的解决方案(感谢@Dan Abramov)是连接每个
,而不仅仅是在顶层连接。今晚我将进行测试。

我有一个新的例子来说明这一点。
您可以这样运行它:

git clone https://github.com/rackt/redux.git

cd redux/examples/tree-view
npm install
npm start

open http://localhost:3000/

丹·阿布拉莫夫溶液在99%的正常情况下都是好的

但是每个增量所需的计算时间与树中的节点数成比例,因为每个连接的节点必须执行少量代码(如身份比较…)。然而,这段代码执行起来非常快

如果您测试Dan Abramov解决方案,我的笔记本电脑上有10k节点,当尝试增加计数器时,我开始看到一些延迟(如100ms延迟)。在便宜的移动设备上,情况可能更糟

有人可能会说,您不应该尝试一次在DOM中呈现10k项,我完全同意这一点,但如果您真的想显示很多项并将它们连接起来,那就没那么简单了

如果要将此O(n)转换为O(1),则可以实现自己的
connect
系统,其中仅在更新基础计数器时触发HOC(高阶组件)订阅,而不是所有HOC订阅

我在这篇文章中介绍了如何做到这一点

我创建了一个on-react redux,以便
connect
变得更加灵活,并允许通过选项轻松定制商店的订阅。其思想是,您应该能够重用
连接
代码,并高效地订阅状态片更改,而不是全局状态更改(即
store.subscribe()

const-mapStateToProps=(state,props)=>{node:selectNodeById(state,props.nodeId)}
常量连接选项={
doSubscribe:(存储,道具)=>store.subscribeNode(props.nodeId)
}
连接(MapStateTrops,未定义,连接选项)(组件连接)

使用
subscribeNode
方法创建存储增强器仍然是您自己的责任。

shouldComponentUpdate
与React组件是否应重新呈现有关,而不是与更新/编辑存储中数据的逻辑有关。显示用于更新存储的代码。如何将数据从存储传递到树组件?您的树组件是如何构造的?是否都是单个组件、嵌套组件、嵌套连接组件?非常感谢这个例子——我已经读过了,但还没有完全弄清楚它在实践中是如何工作的。今晚我将试一试,希望它能解决问题:)这已经足够解决我的MVP问题,所以接受这个解决方案。很高兴看到GitHub上也有很多积极的反馈。谢谢,丹:)链接是404。感谢您进行回购,我认为@NickL建议的链接是正确的,但最好在这里看到对整个过程的描述,以避免只提供链接的答案。我相信这是链接,感谢您提供的信息。只是确认HOC意味着高阶组件?谢谢。我们将来可能会进入数千个节点的领域,当我们的树水平和垂直扩展时,无穷大的解决方案将是棘手的!由于React的时间有限,我正在努力完全理解您提出的解决方案,因此希望了解您如何将自定义连接应用到Dan的解决方案。@Paddyman我将尝试返回一个解决方案。我想先做一个react-redux的PR,这样做很容易,而不必复制react-redux的大部分连接代码。想在GitHub上创建一个问题以便我/其他人可以跟踪进度吗?(我问你,因为你可能会更好地解释这个问题,我不想夸大你的意图)