React - 功能 setState(先前状态)与新的更新值不同?

IT技术 javascript reactjs asynchronous state
2021-04-29 10:37:40

我目前正在尝试React通过多个最近的课程来学习

要更新状态,大多数课程建议采用以下方式:

 const updatedNinjas = [...this.state.ninjas, newNinja];

    this.setState({
      ninjas: updatedNinjas
    });

但是,由于setState是“异步”,官方react文档推荐使用之前的状态,并在此基础上更新。

this.setState(prevState => ({
      ninjas: [...prevState.ninjas, newNinja]
    }));

两者都解决了相同的问题(因为我们在第一个示例中每次都使用一个新数组)还是只是最后一个万无一失?

3个回答

如果您的新状态是根据已处于状态的任何值计算的 - 那么您应该使用setState使用函数的第二种形式

this.setState(prevState => ({
  ninjas: [...prevState.ninjas, newNinja]
}));

甚至:

this.setState(({ninjas}) => ({
  ninjas: [...ninjas, newNinja]
}));

这是由于状态更改是异步的,并且由于性能原因可能会被批处理。

如果您使用某个基于任何状态值的变量更改状态 - 您可以自由使用简单版本:

this.setState({
  answer: 42
});

关于你的

因为我们在第一个例子中每次都使用一个新数组

确实,您每次都会创建一个新数组,但是您使用一些项目集创建它,这些项目React在幕后执行实际状态更改时可能不相关

使用数组设置状态帮助我在分页情况下工作而不会丢失状态中的任何数据

this.setState(prevState => ({
          ninjas: [...prevState.ninjas, ...newNinja]
}));

由于您是初学者,所以我想向您解释一下。

在下面的代码中

...this.state.ninjas

这些......被称为传播语法,所以下面的代码snipet所做的是将现有状态与新项目连接起来;它的结果是重新渲染具有更新状态的组件。

const updatedNinjas = [...this.state.ninjas, newNinja];

    this.setState({
      ninjas: updatedNinjas
    });
至于比较,他们都做同样的事情,react 文档表明第一种方法可能会失败,但并没有说它总是失败,因为我在 1.5 年的 react 经验中从未见过它失败。