javascript - 在 componentDidUpdate 之前调用 React 生命周期渲染
问题描述
我对生命周期顺序/执行的发生方式以及事物在 DOM 中的呈现方式有些困惑。
因此,如果我采用下面的示例,我发现在 5 秒后,控件会render
在转到componentDidUpdate
. 然而,在渲染中,它能够在componentDidUpdate
调用之前打印更新的状态值,即 XYZ。那么这是如何工作的,虽然 componentDidUpdate 说我们可以访问其中的 DOM 节点,但我不知何故认为那componentDidUpdate
是状态实际更新的时候。不知道就我的理解而言差异在哪里?
import React, { Component } from "react";
export default class getSnapshotBeforeUpdateMethod extends Component {
constructor(props) {
console.log("1 constructor");
super(props);
this.state = {
name: "ABC"
};
}
componentDidMount() {
console.log("2a componentDidMount");
setTimeout(() => {
console.log("2b Inside componentDidMount");
this.setState({ name: "XYZ" });
}, 3000);
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("3 getSnapshotBeforeUpdate");
document.getElementById("previous-state").innerHTML =
"The previous state was " + prevState.name;
}
componentDidUpdate() {
console.log("4 componentDidUpdate");
document.getElementById("current-state").innerHTML =
"The current state is " + this.state.name;
}
render() {
console.log("5 render");
return (
<>
<h5>This is a {this.state.name}</h5>
<p id="current-state"></p>
<p id="previous-state"></p>
</>
);
}
}
Codesandbox 链接 https://codesandbox.io/s/class-lifecycle-method-order-0zjk4?file=/src/App.js:0-1055
解决方案
也许回顾一下反应生命周期图可能会有所帮助。
请注意,render
生命周期方法是在“渲染阶段”期间调用的,当 React 渲染出 virtualDOM 以计算它需要提交或刷新到实际 DOM 的差异时。另请注意,此阶段的函数/方法是纯的,没有副作用,并且可能会被 React 暂停、中止或重新启动(强调我的)。
现在请注意,componentDidUpdate
当 DOM 已更新和呈现时,会发生在“提交阶段”。
你console.log
在render
方法中是一个无意的副作用,但它会向你展示它何时被调用相对于componentDidUpdate
.
render
被调用一次,或者可能多次,before componentDidUpdate
被调用一次,每个渲染周期。
推荐阅读
- batch-file - 批量删除以特定方式启动的文件夹
- ios - 无法在 dispatchqueue 中手动控制 performSegue()
- javascript - React Native 更新状态中嵌套对象的单个属性
- laravel - Laravel api 路由不起作用 - 404
- multithreading - WinDbg:如何避免地址/指令断点被错误的线程击中?
- google-cloud-platform - 我是否需要为使用 Google Cloud Platform 的网络应用程序的每个用户提供服务帐户?
- c# - 无法将类型“System.Nullable`1[[System.Int32, ...]]”转换为类型“System.Object”
- python - pythonic for循环编写具有不同变量的excel公式
- sql - SQL 无法将 int 转换为 varchar(15) 值并抛出:将 varchar 值“LBS”转换为数据类型 int 时转换失败
- laravel - 我可以在保存 Laravel Excel 之前更改行吗?