这样做的原因是处理具有state自己功能的变量.我有两种方式可以想到.一种是this.state通过调用状态函数直接变异(好吧,有点,我知道它是不鼓励的),然后调用forceUpdate()并处理它带来的东西.另一种是做回调函数.哪种方法适当?
这是我所谈论的一个例子.我正在使用Vis.js,他们的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));
}
Run Code Online (Sandbox Code Playgroud)
你绝对不应该变异this.state或其中的任何东西.来自React Component API文档:
永远不要直接改变this.state,因为之后调用setState()可能会替换你所做的突变.把this.state看作是不可变的.
setState()不会立即改变this.state,但会创建挂起状态转换.调用此方法后访问this.state可能会返回现有值.
无法保证对setState的调用进行同步操作,并且可以对调用进行批处理以获得性能提升.
除非在shouldComponentUpdate()中实现条件呈现逻辑,否则setState()将始终触发重新呈现.如果正在使用可变对象并且无法在shouldComponentUpdate()中实现逻辑,则仅当新状态与先前状态不同时调用setState()将避免不必要的重新呈现.
即使你的第二个例子在这里也不正确,因为你还在改变this.state.第二个参数仅仅是状态更新时的回调.你想要做的是以某种方式获得新对象并给予它们setState.对Vis.js不太熟悉,这似乎有点棘手,因为它似乎没有任何返回全新/不可变数据集的操作.甚至没有复制或克隆操作.看起来你vis.DataSet每次都必须实际创建一个全新的并添加原始数据,然后添加新数据,然后this.setState( { graphData: newGraphData, ... } )
最终,这可能是"纯粹"和正确的方式来做到这一点.
所有这一切,以及一个大的YMMV警告 - 因为没有明显的方法将vis.DataSets视为不可变的,你可以选择第一个选项.
在文档中采取警告的第一部分:
之后调用setState()可能会替换您所做的突变
在那种情况下会发生什么?没什么,因为你所在州的实际物体是可变的,它只是永远的一个参考.如果React'替换它',它将只是替换它自己.换句话说,只要您从不使用全新的DataSet调用setState,就不会在意外的时间将其替换为意外的内容.
这里的一个大问题是,调用forceUpdate会强制重新渲染,这可能会很慢.但是,无论如何,当你调用该函数时,无论如何你都希望它能够重新渲染,所以......实际上你说你可能还好:)