setState中对于某个state多次修改,只执行一次(最后一次),所以可以将修改放在同一次中
import React, {Component} from 'react';
class Demotest extends Component {
constructor(props) {
super(props);
this.state = {
number: 1
};
}
componentDidMount() {
this.setState({ number: this.state.number + 1 });
}
addNumber(e) {
this.setState({ number: this.state.number + 1 });
this.setState({ number: this.state.number + 1 });
this.setState({ number: this.state.number + 1 });
console.log(this.state.number);
}
render() {
return (
<div>
<div>
<span>当前数字是{this.state.number}</span>
</div>
<br/>
<div>
<button onClick={e => {
this.addNumber(e);
}}>点击添加
</button>
</div>
</div>
);
}
}
export default Demotest;
初始加载后
这时发现页面上显示的是2,控制台输出的却是1,按道理 componentDidMount
?里的应该已经成功了,不然不会显示2,那为什么控制台输出的却是1 呢?
由于 setState
?是异步的所以,所以同步代码执行结束后才会执行,所以在 console.log(‘componentDidMount: ‘, this.state.number);
? 执行的时候 state
?还没有被改变,所以生命周期里的输出还是原来的值。
此时我们点击按钮,触发函数 addNumber
? 发现,函数里的三次 setState
?只生效了一次 ,页面显示的数字变成了3,控制台输出了2?(对应上面代码20行),这是因为多次更新被合并,而异步的原因导致只输出了2。官方文档上明确说明,如果希望通过这里的状态更新一下个状态,需要在 setState
?中使用函数来取得
addNumber(e) {
this.setState((nextState) => {
console.log(nextState.number);
return { number: nextState.number + 1 };
});
this.setState((nextState) => {
console.log(nextState.number);
return { number: nextState.number + 1 };
});
this.setState((nextState) => {
console.log(nextState.number);
return { number: nextState.number + 1 };
});
}
此时输出的是2、3、4
这里要说明的是当你在 ****willMount**
?前设进行 state
?的设置不会 render
?的触发,而事件和可以 componentDidMount
?触发 render
?, 而且原生的事件可以优先这个机制
componentDidMount() {
document.body.addEventListener('click', this.updateData, false);
}
updateData = () => {
this.setState({
number: this.state.number + 1
});
console.log('componentDidMount: ', this.state.number);
};
此处在 componentDidMount
? 上进行的原生事件的绑定, 在此宏任务下添加异步执行的微任务,当点击事件被触发,对应队列中的微任务将会全部被处理,所有微任务会在下次渲染之前被处理结束。具体可查看?JavaScript中的宏任务和微任务.
原文:https://www.cnblogs.com/daixixi/p/12405703.html