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

ylamdve6  于 2023-01-01  发布在  Java
关注(0)|答案(9)|浏览(175)

在循环中调用setSate()是否会阻止它多次更新状态?
我有一个a very basic jsbin,它突出了我所看到的问题。有两个按钮。一个将状态的计数器更新1。另一个在循环中调用One的底层函数--这似乎会多次更新状态。
我知道这个问题的几种解决方案,但我想首先确保我理解了底层机制。为什么不能在循环中调用setState?我是否编写得很笨拙,妨碍了预期的效果?

dba5bblo

dba5bblo1#

从React文档:
setState()将组件状态的更改入队,并通知React需要使用更新后的状态重新呈现此组件及其子组件。这是用于更新用户界面以响应事件处理程序和服务器响应的主要方法。
setState()视为更新组件的请求而不是立即命令。为了获得更好的性能,React可能会延迟更新,然后在一次传递中更新多个组件。React不能保证立即应用状态更改。
setState()并不总是立即更新组件。它可能会成批更新或推迟更新。这使得在调用setState()后立即阅读this.state成为一个潜在的陷阱。
基本上,不要在循环中调用setState,这里发生的事情正是文档所指的:this.state返回先前值,因为尚未应用挂起状态更新。

zazmityj

zazmityj2#

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

const updatedState = {};

if (vars.length) {
  vars.forEach(v => {
    updatedState[v] = '';
    this.setState({
      ...this.state
      ...updatedState,
    });
  });
}
o75abkj4

o75abkj43#

你必须使用这样的东西:

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

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

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

qzlgjiam4#

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

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

希望这能帮上忙。

tf7tbtn2

tf7tbtn25#

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

qvtsj1bj

qvtsj1bj6#

实际上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
   }))
   }
 }
dkqlctbz

dkqlctbz7#

我在创建一个导入项目的功能时遇到了这个问题。由于导入项目的数量可能很大,我需要向网站用户提供反馈(如进度条),以便他们知道他们不是坐在那里等待什么。
因为我们知道不能在循环中执行setState,所以我采用了不同的方法,递归地运行任务。
下面是一个示例代码https://codesandbox.io/s/react-playground-forked-5rssb

svdrlsy4

svdrlsy48#

您可以尝试使用前一个值来增加计数

function handleChange () {
  for(let i=0; i<5; i++) {
      setState (prev=> {
        return prev +1
      })
  }
}
jslywgbw

jslywgbw9#

我能够让您的代码工作,通过执行以下操作在循环中调用setState:

manyClicks() {
   for (i = 0; i < 100; i++) {
     this.setState({clicks: this.state.clicks += 1})
   }
 }
enter code here

希望这能有所帮助!

相关问题