面试经常会被问到React的生命周期,今天有空给大家梳理一遍
一、React生命周期不同于Vue生命周期在几个重要的阶段里面被划分的明明白白,也不同于Vue生命周期名字简洁好记,所以说对于工作经验少的小伙伴来说简直是灾难
二、话不多说直接上总结
挂载阶段(Mounting)
constructor(props)
时机:组件实例化时。
用途:初始化状态(state),绑定事件处理器。
static getDerivedStateFromProps(props, state)
时机:首次渲染之前和每次更新之前。
用途:根据新的 props 计算需要更新的 state。
render()
时机:首次渲染和每次重新渲染时。
用途:返回要渲染的 JSX 或 null。
componentDidMount()
时机:组件挂载后,即第一次渲染到 DOM 后。
用途:执行副作用操作,如网络请求、订阅或设置定时器。
更新阶段(Updating)
static getDerivedStateFromProps(props, state)
时机:更新过程中,在 render 之前。
用途:与挂载阶段相同。
shouldComponentUpdate(nextProps, nextState)
时机:组件接收新的 props 或 state 时。
用途:决定是否需要重新渲染。如果返回 false,则不会触发后续的更新过程。
render()
时机:当 shouldComponentUpdate 返回 true 时。
用途:与挂载阶段相同。
getSnapshotBeforeUpdate(prevProps, prevState)
时机:DOM 更新前,但在最新的 render 输出提交给 DOM 之前。
用途:捕获一些 DOM 的信息(例如滚动位置)。
componentDidUpdate(prevProps, prevState, snapshot)
时机:DOM 更新后。
用途:响应 prop 或 state 变化,进行 DOM 操作或发起网络请求。
卸载阶段(Unmounting)
componentWillUnmount()
时机:组件即将卸载并从 DOM 中移除时。
用途:清理工作,如清除定时器、取消网络请求或取消订阅等。
错误处理
static getDerivedStateFromError(error)
时机:后代组件抛出错误后。
用途:允许组件捕获错误,并根据错误来更新 state。
componentDidCatch(error, info)
时机:后代组件抛出错误后。
用途:记录错误信息,展示错误提示 UI 等。
总结
挂载阶段关注于组件的初始设置和渲染。
更新阶段关注于如何高效地响应数据变化。
卸载阶段确保资源被正确释放。
错误处理提供了处理运行时错误的方法。
三、上代码
//@ts-nocheck
import React, { Component } from 'react';
// 定义一个名为 LifecycleExample 的类,继承自 Component
class LifecycleExample extends Component {
// 构造函数,在组件实例化时调用
constructor(props) {
super(props);
// 初始化组件的状态,count 初始值为 0
this.state = { count: 0 };
console.log('1. Constructor 被调用');
}
// 静态方法,在组件实例化后,每次接收到新的 props 时调用
static getDerivedStateFromProps(nextProps, prevState) {
console.log('2. getDerivedStateFromProps 被调用', nextProps, prevState);
// 返回 null 表示不需要更新 state
return null;
}
// 组件挂载到 DOM 后调用
componentDidMount() {
console.log('4. componentDidMount 被调用');
// 模拟网络请求或设置定时器
setTimeout(() => {
this.setState({ count: this.state.count + 1 });
}, 3000);
}
// 在组件接收到新的 props 或 state 时调用,决定是否需要重新渲染组件
shouldComponentUpdate(nextProps, nextState) {
console.log('5. shouldComponentUpdate 被调用', nextProps, nextState);
// 返回 true 表示允许更新
return true;
}
// 在组件更新前调用,返回一个值,该值会传递给 componentDidUpdate 的第三个参数
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log('6. getSnapshotBeforeUpdate 被调用', prevProps, prevState);
// 返回 null 或者某个值给 componentDidUpdate 的第三个参数
return null;
}
// 在组件更新后调用
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('7. componentDidUpdate 被调用', prevProps, prevState, snapshot);
}
// 在组件卸载前调用,用于清理工作,例如清除定时器
componentWillUnmount() {
console.log('8. componentWillUnmount 被调用');
// 清理工作,例如清除定时器
}
// 渲染组件的 UI
render() {
console.log('3. Render 被调用');
return (
<div>
<h1>Lifecycle Example</h1>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Increment
</button>
</div>
);
}
}
// 导出 LifecycleExample 组件,使其可以在其他文件中被导入和使用
export default LifecycleExample;
四、成果展示
点击按钮前
可以看见生命周期 除了更新部分整个的按钮组件生命走完了
再看点击按钮后
组件实现了更新