在循环中调用 setState 仅更新状态 1 次
Calling setState in a loop only updates state 1 time
在循环中调用setSate()
会阻止它多次更新状态是否有原因?
有一个非常基本的jsbin,可以突出显示我所看到的问题。有两个按钮。一个将状态的计数器更新为 1。另一个在循环中调用 One 的底层函数——它似乎会多次更新状态。
我知道这个问题有几种解决方案,但我想确保我首先了解这里的潜在机制。为什么不能在循环中调用setState
?我是否编码得很笨拙,从而阻止了预期的效果?
来自 React 文档:
setState()
将组件状态的更改排队,并告诉 React 这个组件及其子组件需要使用更新的状态重新渲染。这是用于更新用户界面以响应事件处理程序和服务器响应的主要方法。将
setState()
视为更新组件的请求,而不是即时命令。为了获得更好的感知性能,React 可能会延迟它,然后在一次传递中更新多个组件。React 不保证立即应用状态更改。
setState()
并不总是立即更新组件。它可能会批处理或推迟更新,直到以后。这使得在调用setState()
后立即阅读this.state
成为潜在的陷阱。
基本上,不要在循环中调用setState
。这里发生的事情正是文档所指的:this.state
返回以前的值,因为尚未应用挂起的状态更新。
很好的方法可以在循环中更新状态。只需创建一个空变量,将其值设置为更新状态,调用 setState()
,然后传递给它这个变量:
const updatedState = {};
if (vars.length) {
vars.forEach(v => {
updatedState[v] = '';
this.setState({
...this.state
...updatedState,
});
});
}
你必须使用这样的东西:
const MyComponent = () => {
const [myState, setMyState] = useState([]);
const handleSomething = (values) => {
values.map((value) => {
setMyState((oldValue) => [...oldValue, { key: value.dataWhatYouWant }]);
}
}
return (<> Content... </>);
}
我遇到了同样的问题。但尝试了一点不同的方法。
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>
);
}
我希望这有所帮助。
基本上setState是异步调用的。它还有一个回调函数,一旦状态发生突变,您就可以利用它来做一些事情。此外,如果一个接一个地调用多个 setState,它们将像前面写的那样批处理在一起。
实际上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
}))
}
}
我在创建导入项目的功能时遇到了这个问题。由于导入项目的数量可能很大,我需要向站点用户提供反馈(如进度条(,以便他们知道他们不会坐在那里等待任何东西。
由于我们知道我们不能在循环中setState
,因此我采取了不同的方法,以递归方式运行任务。
下面是一个示例代码https://codesandbox.io/s/react-playground-forked-5rssb
您可以使用以前的值尝试此操作以增加计数。
function handleChange() {
for (let i = 0; i < 5; i++) {
setState(prev => {
return prev + 1
})
}
}
我能够使您的代码正常工作,通过执行以下操作在循环中调用 setState:
manyClicks() {
for (i = 0; i < 100; i++) {
this.setState({clicks: this.state.clicks += 1})
}
}
enter code here
希望这有帮助!
- 更新Redux状态&然后在同一实例中获取更新状态
- 如果我不应该在组件WillUpdate中调用setState,如何更新状态(使用ReactJS)
- 如何在alt.js中使用源成功请求后更新状态
- 实现已验证用户更新状态的最佳方式,作为对系统中已更改状态的反应.(ASP.NET MVC网站)
- 如何使用Redux更新状态
- 使用 OnChange 事件更新状态具有延迟字符
- 在 redux 化简器中更新状态的正确方法
- 在反应本机中更新状态需要很长时间
- React - 如何在 AJAX 请求后更新状态
- onchange 事件更新状态,延迟为 1 个字符
- 在循环中调用 setState 仅更新状态 1 次
- react js和rails在具有活动记录关系的组件上更新状态
- React componentDidMount未更新状态
- 发送整个对象只是为了更新状态
- Javascript的问题.无法更新状态
- 当视图加载时更新状态
- Twitter REST API,更新状态
- 在React Router中,当页面改变时更新状态
- React-redux, connect函数不使用新数据更新状态
- React:将新插入的子元素返回给父元素以更新状态