我已经在Codepen中写了一个测试用例
通过单击按钮运行测试,然后从浏览器控制台查看结果。
您可以从控制台日志中看到,即使我在之前 setState
多次调用await
,它也只会更新一次组件。
但是如果我在之后 setState
多次调用await
,它也会多次更新组件。
知道为什么会这样吗?
代码:
/*
* A simple React component
*/
class Application extends React.Component {
state = {
value: 0
}
onClickHandler = (e) => {
this.runAsyncFunc();
}
runAsyncFunc = async() => {
console.log('BEFORE AWAIT');
this.setState({ value: 1 });
this.setState({ value: 1 });
this.setState({ value: 1 });
await setTimeout(()=>{}, 2000);
console.log('AFTER AWAIT');
this.setState({ value: 1 });
this.setState({ value: 1 });
this.setState({ value: 1 });
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('updated');
}
render() {
return <div>
<p>{this.state.value}</p>
<button onClick={this.onClickHandler}>RUN TEST</button>
<p>Please check from Browser Console's Log</p>
</div>;
}
}
/*
* Render the above component into the div#app
*/
React.render(<Application />, document.getElementById('app'));
答案 0 :(得分:2)
之所以发生这种情况,是因为当this answer states React尝试批处理setState
调用并在可能的时候一起处理它们。但这不是异步计算的情况,因为React(以及一般人)无法预测和再现setState
的被异步调用的顺序。
因此,在您的情况下,它会退回到仅更新3次状态。
答案 1 :(得分:1)
您可以从React.Component生命周期文档(https://reactjs.org/docs/react-component.html)中获得答案
componentDidUpdate() is invoked immediately after updating occurs. This method is not called for the initial render.
使用此方法shouldComponentUpdate()
。如果没有理由应用新的渲染,则此方法允许您的组件退出更新生命周期。开箱即用,shouldComponentUpdate()是一个无操作的返回true。这意味着每次我们在组件中启动更新时,我们都会重新渲染。
我添加了更多代码
shouldComponentUpdate = function(nextProps, nextState) {
return nextState.value !== this.state.value;
}
// Change value will set after await
runAsyncFunc = async() => {
console.log('BEFORE AWAIT');
this.setState({ value: 1 });
this.setState({ value: 1 });
this.setState({ value: 1 });
await setTimeout(()=>{}, 2000);
console.log('AFTER AWAIT');
this.setState({ value: 2 });
this.setState({ value: 2 });
this.setState({ value: 2 });
}
检查我的Codepen
因此,如果您要防止不必要的渲染自定义方法shouldComponentUpdate