关于以下代码:
import React from "react";
export default class App extends React.Component {
state = {
count: 0
};
componentDidMount() {
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
setTimeout(() => {
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
}, 0);
}
render() {
return "123";
}
}
如果使用 ReactDOM.render 日志将是 0,0,2,3,但对于 createRoot 日志将是 0,0,1,1,谁能帮忙解释一下原因?
ReactDOM.render 和 createRoot 之间行为差异的原因是 React 出于性能原因安排更新和批处理它们的方式。
使用 ReactDOM.render,更新是同步处理的,并且 componentDidMount 中发生的状态变化将被一起批处理。因此,当状态在 componentDidMount 中更新两次时,控制台日志将输出 0,然后再次输出 0,因为这两次状态更新是一起批处理的。
然而,对于 createRoot,React 使用不同的更新批处理策略。在这种情况下,componentDidMount 中的初始状态更新将与 setTimeout 回调中的第一个 setState 调用一起被批处理,因为它们发生在同一个“批处理窗口”中。这意味着控制台日志将输出 0,然后再次输出 0,因为这些更新是一起批处理的。然后,在下一个“批处理窗口”处理完 setTimeout 回调后,接下来的两个状态更新将被一起批处理,并导致控制台日志输出 1,然后再次输出 1。
简而言之,ReactDOM.render 和 createRoot 之间的行为差异是由于 React 出于性能原因安排更新和批处理它们的方式不同。