是否有理由在循环中调用setSate()
会阻止它多次更新状态?
我a very basic jsbin突出了我所看到的问题。有两个按钮。一个将状态计数器更新为1.另一个在循环中调用One的基础函数 - 这似乎会多次更新状态。
我知道这个问题的几个解决方案,但我想确保我首先理解这里的基础机制。为什么不能在循环中调用setState
?我是否笨拙地编码阻止了预期的效果?
答案 0 :(得分:10)
来自React Docs:
setState()不会立即改变this.state但会创建一个 待定状态转换。调用后访问this.state 方法可以返回现有值。没有 保证调用setState和调用的同步操作 为获得业绩增长而受到批评。
基本上,不要在循环中调用setState
。这里发生的正是文档所指的内容:this.state
正在返回之前的值,因为尚未应用挂起状态更新。
答案 1 :(得分:1)
我遇到了同样的问题。但尝试采用一种不同的方法。
iterateData(data){
//data to render
let copy=[];
for(let i=0;<data.length;i++){
copy.push(<SomeComp data=[i] />)
}
this.setState({
setComp:copy
});
}
render(){
return(
<div>
{this.state.setComp}
</div>
);
}
我希望这会有所帮助。
答案 2 :(得分:1)
在循环中更新状态有一种很好的方法。只需创建一个空变量,将其值设置为更新状态,调用setState()
,并将此变量传递给它:
const updatedState = {};
if (vars.length) {
vars.forEach(v => {
updatedState[v] = '';
this.setState({
...this.state
...updatedState,
});
});
}
答案 3 :(得分:1)
你必须使用类似的东西:
const MyComponent = () => {
const [myState, setMyState] = useState([]);
const handleSomething = (values) => {
values.map((value) => {
setMyState((oldValue) => [...oldValue, { key: value.dataWhatYouWant }]);
}
}
return (<> Content... </>);
}
答案 4 :(得分:1)
实际上 setState()
方法是异步的。相反,您可以像这样实现它
manyClicks() {
var i = 0;
for (i = 0; i < 100; i++) {
//this.setState({clicks: this.state.clicks + 1}); instead of this
this.setState((prevState,props)=>({
clicks: ++prevState.clicks
}))
}
}
答案 5 :(得分:0)
基本上,setState是异步调用的。它还具有回调函数,一旦状态发生变异,您就可以利用它来执行某些操作。 此外,如果一个接一个地调用多个setStates,它们将按照之前的编写方式进行批处理。
答案 6 :(得分:0)
我在创建导入项目的功能时遇到了这个问题。 由于导入项目的数量可能很大,我需要向站点用户提供反馈(如进度条),以便他们知道他们不会坐在那里等待任何事情。
我们知道我们不能在循环中 setState
,我采用了不同的方法,通过递归运行任务。
这是一个示例代码 https://codesandbox.io/s/react-playground-forked-5rssb
答案 7 :(得分:-5)
我能够使你的代码工作,通过执行以下操作在循环中调用setState:
manyClicks() {
for (i = 0; i < 100; i++) {
this.setState({clicks: this.state.clicks += 1})
}
}
enter code here
希望这有帮助!