可以将setState函数的prevState参数视为可变的吗?
答案是“ 不”,
您永远都不要突变
prevState,这在setState部分的 react 文档中也有明确提及
prevState是对先前状态的引用。它不应该直接突变。相反,更改应通过根据prevState和props的输入构建一个新对象来表示。
经过测试
prevState,
this.state它们是相同的,实际上它们不是。
为了弄清楚它们为何真正不同,我们需要知道为什么
prevState真正存在,答案是该
setState函数是异步的,这就是为什么react
js允许我们访问的原因,
prevState请检查下面的示例
prevState != this.state
在下面的示例中,我们将为每次点击增加两次计数器,但是我们将使用2次
setState*** 作,每个 *** 作都会使计数器增加1。
因为
setState是
async你会发现,第二
setState*** 作开始之前先
setState完成这就是
prevState是有用的,在这里
prevState和
this.state不相等。
我在每行注释了一个数字,表示执行该行的时间,这应该说明我们为什么需要
prevState它,以及为什么它不同于
this.state。
class App extends React.Component{ constructor(props) { super(props); this.state = { counter : 1 }; } increment = () =>{ this.setState((prevState , props) => { console.log("in first"); //3 console.log(prevState); //3 console.log(this.state); //3 if(prevState == this.state) { console.log("in first prevState == this.state"); } return { counter : prevState.counter+1 } } , ()=>{ console.log("done updating first"); //5 }); console.log("after first"); //1 this.setState((prevState, props) => { console.log("in second"); //4 console.log(this.state); //4 console.log(prevState); //4 if (prevState == this.state) { console.log("in second prevState == this.state"); } return { counter: prevState.counter + 1 } } , () =>{ console.log("done updating second"); //6 }); console.log("after second"); //2 } render(){ return ( <div> <span>{this.state.counter}</span> <br/> <button onClick={this.increment} >increment</button> </div> ) }}
上面代码的结果是
"after first""after second""in first"▶Object {counter: 1}▶Object {counter: 1}"in first prevState == this.state""in second"▶Object {counter: 1}▶Object {counter: 2}"done updating first""done updating second"
上面的代码在此链接中完全可用,您可以检查console.log结果
https://presandbox.io/s/k325l485mr
上面的示例将正确地使计数器每次点击增加两次,如果您想中断它,请在第二秒内更改change语句
setState
从
return { counter: prevState.counter + 1}
至
return { counter: this.state.counter + 1}
并且您会发现结果不正确,因为每次点击都会导致1的增量,这是不正确的,因为我们有2
setState,这是因为我们没有使用
prevState并且使用了不正确的
this.state最后
我相信更新计数器的正确方法是
this.setState((prevState) => ({ counter: prevState.counter + 1 }));
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)