我正在学习React,这是我第一次处理异步操作。目前,我正在构建一个简单的计算器,在使用setState之后立即尝试访问该状态时遇到了一些小问题。解决问题很容易,因为我的应用程序非常简单。但是,我无法找到确定的规则来确定调用setState之后要花多长时间才能确定状态实际上已被更新。需要一定的时间吗?是否取决于我的代码结构?另外,在setState之后使用setTimeout以便给状态时间更新是否合适?如果有人可以让我了解一下React何时会更新状态并为我省去猜测,那将不胜感激。
答案 0 :(得分:6)
需要一定的时间吗?
没有具体金额。
这取决于我的代码结构吗?
一般来说,但这不是问题所在。 :-)
另外,在setState之后使用setTimeout以便给状态时间更新是否合适?
否。
在React中调用setState后,在访问/更改状态时是否有严格的规则来避免异步错误?
是的。它们已包含在文档中,尤其是here。它们(至少)是:
知道状态已完成更改的唯一方法是使用componentDidUpdate
或您可以提供给setState
的完成回调(第二个参数):
this.setState(newState, () => {
// `this.state` has the updated state
});
如果要基于现有状态更改状态,则必须使用setState
的形式,该形式接受一个函数作为其第一个参数,并以最新状态调用该函数,以便改变。
(不特定于异步。)从不直接修改状态对象或它引用的任何对象。
因此,例如:假设您有一个数组(items
),并且如果该数组还不存在,则需要将其推入其中:
// WRONG, breaks Rule #3
if (!this.state.items.includes(newItem)) {
this.state.items.push(newItem);
}
// WRONG, breaks Rule #2
if (!this.state.items.includes(newItem)) {
this.setState({items: [...items, newItem]});
}
// WRONG, breaks Rule #1
this.setState({items: [...items, newItem]});
doSomethingWith(this.state.items);
相反:
this.setState(
({items}) => {
if (!items.includes(newItem)) {
return {items: [...items, newItem]};
}
},
() => {
doSomnethingWith(this.state.items);
}
);
但是请注意,使用完成回调(上面的第二个函数)通常是一种反模式;确实,重新渲染状态更新时组件唯一要做的事情是,React会为您调用render
。
但是,此答案不是不是替代阅读the documentation的方法。 :-)
答案 1 :(得分:2)
setState
将回调作为第二个参数:
this.setState({
foo: 'bar'
}, () => {
// This code will be executed after setState has been processed
});
答案 2 :(得分:0)
如果要访问Any?
之后的状态,可以在回调函数中执行相同的操作,以验证实际状态是否正在更新。
像这样:
setState()
每当状态更改时,它都会比较DOM和虚拟DOM以找出差异,并将它们呈现在实际DOM上。
答案 3 :(得分:0)
理想情况下,您的组件不关心create table AssetMachines (
AssetMachine_Id serial primary key,
Asset_Id int references assets(asset_id),
Machine_Id int references machines(machine_id),
. . . -- more columns can go here
);
更新的时间。
您最可能要寻找的是基于先前状态的setState
通话...
setState
再次,从那里,您的组件不必在乎React实际上何时执行更新! (与所有事物一样,当然也有例外)