ReactJS - 组件生命周期
在 React 中,组件的生命周期表示组件存在期间的不同阶段。React 提供回调函数来在 React 生命周期的每个阶段附加功能。让我们在本章中学习 React 组件的生命周期(和相关 API)。
生命周期 API
每个 React 组件都有三个不同的阶段。
挂载 − 挂载表示在给定的 DOM 节点中渲染 React 组件。
更新 − 更新表示在状态更改/更新期间在给定的 DOM 节点中重新渲染 React 组件。
卸载 −卸载表示移除 React 组件。
React 提供了一组生命周期事件(或回调 API)来附加功能,这些功能将在组件的各个阶段执行。生命周期的可视化以及生命周期事件(API)的调用顺序如下所示。

constructor() − 在 React 组件的初始构造阶段调用。用于设置组件的初始状态和属性。
render() − 在组件构造完成后调用。它在虚拟 DOM 实例中渲染组件。这被指定为在 DOM 树中安装组件。
componentDidMount() −在 DOM 树中初始安装组件后调用。这是调用 API 端点和执行网络请求的最佳位置。在我们的时钟组件中,可以在此处设置 setInterval 函数以每秒更新状态(当前日期和时间)。
componentDidMount() { this.timeFn = setInterval( () => this.setTime(), 1000); }
componentDidUpdate() − 与 ComponentDidMount() 类似,但在更新阶段调用。此阶段可以进行网络请求,但前提是组件的当前属性和先前属性存在差异。
API 的签名如下 −
componentDidUpdate(prevProps, prevState, snap)
prevProps − 组件的先前属性。
prevState − 组件的先前状态。
snapshot − 当前渲染的内容。
componentWillUnmount() −组件从 DOM 卸载后调用。这是清理对象的好地方。在我们的时钟示例中,我们可以在此阶段停止更新日期和时间。
componentDidMount() { this.timeFn = setInterval( () => this.setTime(), 1000); }
shouldComponentUpdate() − 在更新阶段调用。用于指定组件是否应更新。如果返回 false,则不会发生更新。
签名如下 −
shouldComponentUpdate(nextProps, nextState)
nextProps − 组件的即将出现的属性
nextState − 组件的即将出现的状态
getDerivedStateFromProps − 在初始和更新阶段以及 render() 方法之前调用。它返回新的状态对象。在属性更改导致状态更改的情况下很少使用它。它主要用于动画上下文中,其中需要组件的各种状态来实现流畅的动画。
API 的签名如下 −
static getDerivedStateFromProps(props, state)
props − 组件的当前属性
state − 组件的当前状态
这是一个静态方法,无法访问 this 对象。
getSnapshotBeforeUpdate − 在渲染内容提交到 DOM 树之前调用。它主要用于获取有关新内容的一些信息。此方法返回的数据将传递给 ComponentDidUpdate() 方法。例如,它用于维护用户在新生成的内容中的滚动位置。它返回用户的滚动位置。此滚动位置由componentDidUpdate()用于设置输出在实际DOM中的滚动位置。
API的签名如下 −
getSnapshotBeforeUpdate(prevProps, prevState)
prevProps − 组件的先前属性。
prevState − 组件的先前状态。
生命周期API的工作示例
让我们在我们的react-clock-app应用程序中使用生命周期API。
步骤1 −在您最喜欢的编辑器中打开 react-clock-hook-app。
打开 src/components/Clock.js 文件并开始编辑。
步骤 2 − 从构造函数中删除 setInterval() 方法。
constructor(props) { super(props); this.state = { date: new Date() } }
步骤 3 − 添加 componentDidMount() 方法并调用 setInterval() 每秒更新日期和时间。此外,存储引用以便稍后停止更新日期和时间。
componentDidMount() { this.setTimeRef = setInterval(() => this.setTime(), 1000); }
添加 componentWillUnmount() 方法并调用 clearInterval() 以停止日期和时间更新调用。
componentWillUnmount() { clearInterval(this.setTimeRef) }
现在,我们已经更新了 Clock 组件,该组件的完整源代码如下所示−
import React from 'react'; class Clock extends React.Component { constructor(props) { super(props); this.state = { date: new Date() } } componentDidMount() { this.setTimeRef = setInterval(() => this.setTime(), 1000); } componentWillUnmount() { clearInterval(this.setTimeRef) } setTime() { this.setState((state, props) => { console.log(state.date); return { date: new Date() } }) } render() { return ( <div> <p>The current time is {this.state.date.toString()}</p> </div> ); } } export default Clock;
接下来,打开 index.js 并使用 setTimeout 在 5 秒后从 DOM 中删除时钟。
import React from 'react'; import ReactDOM from 'react-dom'; import Clock from './components/Clock'; ReactDOM.render( <React.StrictMode> <Clock /> </React.StrictMode>, document.getElementById('root') ); setTimeout(() => { ReactDOM.render( <React.StrictMode> <div><p>Clock is removed from the DOM.</p></div> </React.StrictMode>, document.getElementById('root') ); }, 5000);
使用 npm 命令为应用程序提供服务。
npm start
打开浏览器并在地址栏中输入 http://localhost:3000 并按 Enter。
时钟将显示 5 秒,然后从 DOM 中删除。通过检查控制台日志,我们可以发现清理代码已正确执行。

Expense Manager(费用管理器)应用程序中的生命周期 API
让我们在Expense Manager(费用管理器)中添加生命周期 API,并在调用该 API 时记录它。这将提供有关组件生命周期的见解。
步骤 1 −在您最喜欢的编辑器中打开 expense-manager 应用程序。
接下来,使用以下方法更新 ExpenseEntryItemList 组件。
componentDidMount() { console.log("ExpenseEntryItemList :: Initialize :: componentDidMount :: Component mounted"); } shouldComponentUpdate(nextProps, nextState) { console.log("ExpenseEntryItemList :: Update :: shouldComponentUpdate invoked :: Before update"); return true; } static getDerivedStateFromProps(props, state) { console.log("ExpenseEntryItemList :: Initialize / Update :: getDerivedStateFromProps :: Before update"); return null; } getSnapshotBeforeUpdate(prevProps, prevState) { console.log("ExpenseEntryItemList :: Update :: getSnapshotBeforeUpdate :: Before update"); return null; } componentDidUpdate(prevProps, prevState, snapshot) { console.log("ExpenseEntryItemList :: Update :: componentDidUpdate :: Component updated"); } componentWillUnmount() { console.log("ExpenseEntryItemList :: Remove :: componentWillUnmount :: Component unmounted"); }
步骤 2 − 使用 npm 命令为应用程序提供服务。
npm start
打开浏览器并在地址栏中输入 http://localhost:3000 并按 Enter。
接下来,检查控制台日志。它将显示初始化阶段的生命周期 api,如下所示。
ExpenseEntryItemList :: Initialize / Update :: getDerivedStateFromProps :: Before update ExpenseEntryItemList :: Initialize :: componentDidMount :: Component mounted
删除一个项目,然后检查控制台日志。它将显示更新阶段的生命周期 api,如下所示。
ExpenseEntryItemList :: Initialize / Update :: getDerivedStateFromProps :: Before update ExpenseEntryItemList.js:109 ExpenseEntryItemList :: Update :: shouldComponentUpdate invoked :: Before update ExpenseEntryItemList.js:121 ExpenseEntryItemList :: Update :: getSnapshotBeforeUpdate :: Before update ExpenseEntryItemList.js:127 ExpenseEntryItemList :: Update :: componentDidUpdate :: Component updated
最后,删除所有生命周期 API,因为它们可能会影响应用程序性能。只有在情况需要时才应使用生命周期 API。