Reactjs-setState以前的状态是第一个参数,props是第二个参数

Qui*_*der 10 javascript setstate reactjs

我在这篇官方文章中读过以下这些文章:

this.props并且this.state可以异步更新,您不应该依赖它们的值来计算下一个状态.

任何人都可以通过举例说明以下代码试图实现的内容.

 this.setState((prevState, props) => ({
  couter: prevState.counter + props.increment
}));
Run Code Online (Sandbox Code Playgroud)

我指的是reactjs React.js的官方网站

Bru*_*rdo 25

他们说你应该这样做而不是下面的例子.

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
Run Code Online (Sandbox Code Playgroud)

如果你这样访问,他们无法保证状态将具有正确的值因为setState()将异步发生,可能会发生其他更新并更改值.如果你要根据以前的状态计算状态,你必须确保你有最后一个和最新的值,所以他们让setState()接受一个用prevStateprops调用的函数,所以你可以具有更新状态的正确值,如下例所示.

 // Correct
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));
Run Code Online (Sandbox Code Playgroud)


小智 5

为了增加布鲁诺的答案,上述正确的函数称为函数。React有一个叫做不变性的东西,这意味着每个声明的值都应该尽可能地从其原始声明中更改。在传递函数之前,该函数中的变量不是您的实际道具和状态,这意味着在javascript函数堆栈(将同步和异步调用排队的线程)上,值和对属性的引用将以不同方式存储,从而造成不确定性在“错误”情况下的值是多少。


小智 5

根据之前的状态更新状态

\n

假设年龄是 42 岁。该处理程序调用 setAge(age + 1) 三次:

\n
function handleClick() {\n  setAge(age + 1); // setAge(42 + 1)\n  setAge(age + 1); // setAge(42 + 1)\n  setAge(age + 1); // setAge(42 + 1)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然而,一点击,年龄就只有43岁,而不是45岁!这是因为调用 set 函数不会更新已运行代码中的年龄状态变量。因此,每个 setAge(age + 1) 调用都会变成 setAge(43)。

\n

要解决此问题,您可以将更新程序函数传递给 setAge 而不是下一个状态:

\n
function handleClick() {\n  setAge(a => a + 1); // setAge(42 => 43)\n  setAge(a => a + 1); // setAge(43 => 44)\n  setAge(a => a + 1); // setAge(44 => 45)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

a => a + 1是您的更新程序功能。它获取待处理状态并从中计算下一个状态。

\n

React 将您的更新器函数放入队列中。然后,在下一次渲染期间,它将以相同的顺序调用它们:

\n

a => a + 1将接收 42 作为待处理状态并返回 43 作为下一个状态。

\n

a => a + 1将接收 43 作为待处理状态并返回 44 作为下一个状态。

\n

a => a + 1将接收 44 作为待处理状态,并返回 45 作为下一个状态。\n没有其他排队更新,因此 React 最终将存储 45 作为当前状态。

\n

按照惯例,通常将挂起状态参数命名为状态变量名称的第一个字母,例如 forage。不过,您也可以将其称为 prevAge 或您认为更清晰的其他名称。

\n

React 可能会在开发过程中调用您的更新程序两次以验证它们是否纯净。

\n