在循环中调用 setState 仅更新状态 1 次

IT技术 javascript reactjs
2021-01-23 03:18:16

是否有理由setSate()在循环中调用会阻止它多次更新状态?

我有一个非常基本的 jsbin,它突出了我所看到的问题。有两个按钮。一个将状态的计数器更新为 1。另一个在循环中调用 One 的底层函数——这似乎会多次更新状态。

我知道这个问题的几种解决方案,但我想确保我首先了解这里的底层机制。为什么不能setState在循环中调用?我是否笨拙地编码以阻止预期的效果?

6个回答

来自React 文档

setState()将组件状态的更改加入队列,并告诉 React 该组件及其子组件需要使用更新后的状态重新渲染。这是您用来更新用户界面以响应事件处理程序和服务器响应的主要方法。

将其setState()视为更新组件的请求而不是立即命令。为了更好的感知性能,React 可能会延迟它,然后一次更新多个组件。React 不保证立即应用状态更改。

setState()并不总是立即更新组件。它可能会批量更新或推迟更新。这使得this.state在调用setState()潜在陷阱后立即阅读

基本上,不要setState循环调用这里发生的事情正是文档所指的:this.state返回先前的值,因为尚未应用挂起状态更新。

这个答案节省了我上传状态处理 tvm 的一周
2021-03-14 03:18:16
我不知道我是如何在文档中遗漏的,但谢谢你。这更有意义。
2021-03-17 03:18:16
这是因为他在打电话this.setState({clicks: this.state.clicks += 1});,这真是个坏主意。+=是直接改变状态,而不是让 React 通过setState批量更新来完成。
2021-03-28 03:18:16
请注意,有一种setState接受函数并允许您访问当前状态的形式,并且在此实例中确实有效。参见jsbin.com/kiyaco/edit?js,输出示例。
2021-04-02 03:18:16
好的。我实际上不知道您可以将函数传递给setState
2021-04-08 03:18:16

有一种在循环中更新状态的好方法。只需创建一个空变量,将其值设置为更新后的状态,调用setState(),并将此变量传递给它:

const updatedState = {};

if (vars.length) {
  vars.forEach(v => {
    updatedState[v] = '';
    this.setState({
      ...this.state
      ...updatedState,
    });
  });
}
哇,如果 setState 被粉碎为一个,则绕过多个调用的 React 优化的完美而干净的方法。
2021-03-25 03:18:16

我有同样的问题。但是尝试了一些不同的方法。

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>
   );
 }

我希望这有帮助。

你必须使用这样的东西:

const MyComponent = () => {
  const [myState, setMyState] = useState([]);

  const handleSomething = (values) => {
    values.map((value) => {
      setMyState((oldValue) => [...oldValue, { key: value.dataWhatYouWant }]);
    }
  }

  return (<> Content... </>);
}

基本上 setState 被异步调用。它还有一个回调函数,一旦状态发生变化,你就可以利用它来做一些事情。此外,如果多个 setState 一个接一个地被调用,它们会像之前写的那样一起批处理。