react setState同步更新与异步更新
学习react相关的文档知识,有些过时的信息需要及时校正,比如这个setState的同步&异步更新问题以前也是常见的面试题,在react18之后他的答案又变化了,能力的提升就是踩坑的频次。(⊙o⊙)…
言归正传
举个例子
我们有如下代码,是一个常见的面试题
import * as React from 'react';
export default class App extends React.Component {
state = {
name: 'abc',
};
componentDidMount() {
this.setState({ name: 'didmount' });
console.log(this.state.name);
setTimeout(() => {
// setTimeout中调用
console.log('setTimeout: pre----' + this.state.name);
this.setState({ name: 'setTimeout' });
console.log('setTimeout:==== ' + this.state.name);
}, 0);
document.getElementById('div2').addEventListener('click', this.increment2);
}
increment = () => {
// 合成事件中调用
console.log('react increment==== ' + this.state.name);
this.setState({ name: 'increment' });
console.log('react event: ' + this.state.name);
};
increment2 = () => {
// 原生事件中调用
console.log('dom event: ====' + this.state.name);
this.setState({ name: 'dom event' });
console.log('dom event: ' + this.state.name);
};
render() {
return (
<div className="App">
<h2>couont: {this.state.name}</h2>
<div id="div1" onClick={this.increment}>
{React.version}increment1
</div>
<div id="div2">click me and increment2</div>
</div>
);
}
}
在React 18 之前,
只在React 事件处理函数中进行批异步更新。
默认情况下,在promise、setTimeout、原生事件处理函数中、或任何其它事件内的更新都是同步的
在React 18 之后
import * as React from 'react';
import * as ReactDom from 'react-dom';
import App from './App';
import { createRoot } from 'react-dom/client';
const rootElement = document.getElementById('root');
// 异步测试 --react18 推荐语法
//createRoot(rootElement).render(<App />);
// 同步测试 --react18 废弃语法
ReactDom.render(<App />, rootElement);
当你用 ReactDom.render 挂载节点的时候会运行得到的效果就是
只在React 事件处理函数中进行批异步更新,其他的 promise、setTimeout、原生事件处理函数中的更新都是同步的
当你用 createRoot(rootElement).render(); 挂载节点的时候,
所有的更新都是异步的。
本文作者:番茄炒蛋
本文地址: https://www.noway.pub/2023/09/07/react_setState/
版权声明:转载请注明出处!