原因是在处理时state
具有自己功能的变量。我能想到的有两种方法。一是变异this.state
直接(嗯,有点,我知道这是不鼓励的)通过调用状态函数,然后调用forceUpdate()
并处理由此带来的后果。另外就是做回调函数。哪个是正确的方法?
这是我正在谈论的一个例子。我正在与Vis.js http://visjs.org,并且它们的 DataSet 对象允许您将数据添加到现有数据集 - 例如节点和边。
addDataToGraph: function(data) {
// Is this the proper way to do something like this?
this.state.graphData.nodes.add(nodes);
this.state.graphData.edges.add(edges);
this.forceUpdate();
// Or is this the right way - the question I am posing here
this.setState({
currentChunk: data.currentChunk,
totalChunks: data.totalChunks
}, function() {
this.state.graphData.nodes.add(data.nodes);
this.state.graphData.edges.add(data.edges);
}.bind(this));
}
你绝对不应该变异this.state
,或者其中的任何东西,永远。来自React 组件 API 文档 https://facebook.github.io/react/docs/component-api.html#setstate:
永远不要直接改变 this.state,因为之后调用 setState() 可能会替换您所做的改变。将 this.state 视为不可变的。
setState() 不会立即改变 this.state ,而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。
无法保证 setState 调用的同步操作,并且可以对调用进行批处理以提高性能。
setState() 总是会触发重新渲染,除非在 shouldComponentUpdate() 中实现了条件渲染逻辑。如果使用可变对象并且逻辑无法在 shouldComponentUpdate() 中实现,则仅在新状态与先前状态不同时调用 setState() 将避免不必要的重新渲染。
即使你的第二个例子在这里也不正确,因为你仍在变异this.state
。第二个参数只是状态更新时的回调。你想要做的就是以某种方式获取新对象并将其提供给setState
。由于不太熟悉 Vis.js,这似乎有点棘手,因为它似乎没有任何返回全新/不可变数据集的操作。甚至没有复制或克隆操作。看起来你必须真正制作一个全新的vis.DataSet
每次添加原始数据,然后添加新数据,然后this.setState( { graphData: newGraphData, ... } )
最终,这可能是“纯粹”且正确的方法。
话虽如此,但还有一个 YMMV 警告——因为没有明显的治疗方法vis.DataSet
由于它是不可变的,您可能可以选择第一个选项。
以文档中警告的第一部分为例:
之后调用 setState() 可能会替换您所做的突变
那样的话会发生什么?没什么,因为你的状态中的实际对象是可变的,它永远只是一个引用。如果 React“替换它”,它只是用它自己替换它。换句话说,只要您从未使用全新的 DataSet 调用 setState,它就不会在意外的时间被意外的内容替换。
这里最大的问题是调用forceUpdate
将会强制重新渲染,这可能会很慢。但听起来你希望它在调用该函数时无论如何都重新渲染,所以......务实地说你可能还好:)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)