面试题:React 生命周期有哪些阶段?每个阶段对应的函数是什么?

React 组件的生命周期描述了组件从创建到销毁的整个过程。在 React 16.3 版本之后,生命周期方法发生了重要更新,引入了新的静态生命周期方法,并标记了一些旧方法为不安全(即将废弃)

以下是 React 类组件生命周期的三个主要阶段及其对应的生命周期函数:


阶段一:挂载阶段 (Mounting)

组件被创建并插入到 DOM 中。

生命周期函数说明
constructor(props)初始化:组件构造函数,用于初始化 state 和绑定事件处理函数。必须调用 super(props)
static getDerivedStateFromProps(props, state)状态派生:在 render 之前调用,用于根据 props 更新 state。返回一个对象来更新 state,或返回 null 不更新。很少使用。
render()渲染:唯一必需的方法。返回 JSX,描述 UI 结构。必须是纯函数,不能修改 state 或与 DOM 交互。
componentDidMount()挂载完成:组件已插入 DOM。适合进行数据获取 (API 调用)、设置定时器、操作 DOM 等操作。

执行顺序constructorgetDerivedStateFromPropsrendercomponentDidMount


阶段二:更新阶段 (Updating)

propsstate 发生变化时,组件重新渲染。

生命周期函数说明
static getDerivedStateFromProps(props, state)render 之前调用,用于根据新的 props 同步更新 state
shouldComponentUpdate(nextProps, nextState)性能优化:决定组件是否需要重新渲染。返回 true(默认)则继续,返回 false 则跳过更新。常用于 React.PureComponent 或手动优化。
render()重新渲染组件。
getSnapshotBeforeUpdate(prevProps, prevState)获取快照:在 DOM 更新前被调用,可以读取 DOM 的当前状态(如滚动位置)。返回的值会作为第三个参数传递给 componentDidUpdate
componentDidUpdate(prevProps, prevState, snapshot)更新完成:组件已更新并重新渲染到 DOM。适合进行DOM 操作、网络请求(需对比 props 防止无限循环)

执行顺序getDerivedStateFromPropsshouldComponentUpdaterendergetSnapshotBeforeUpdatecomponentDidUpdate


阶段三:卸载阶段 (Unmounting)

组件从 DOM 中被移除。

生命周期函数说明
componentWillUnmount()清理工作:在组件卸载和销毁前调用。必须在此方法中清理副作用,如:清除定时器、取消网络请求、移除事件监听器、清理订阅等。

已废弃或即将废弃的生命周期方法(不推荐使用)

这些方法在异步渲染中可能导致问题,React 16.3+ 已标记为不安全。

旧方法问题替代方案
componentWillMount()已移除。使用 constructorcomponentDidMount
componentWillReceiveProps(nextProps)props 更新时调用,但容易误用导致状态不一致。使用 getDerivedStateFromPropsuseEffect(函数组件)。
componentWillUpdate(nextProps, nextState)在更新前调用,但不允许修改 state使用 getSnapshotBeforeUpdate

注意:在 React 17+ 中,这些方法需要加上 UNSAFE_ 前缀才能使用(如 UNSAFE_componentWillMount),以警示开发者。


错误处理阶段 (Error Handling)

当渲染过程、生命周期方法或子组件构造函数中发生错误时。

生命周期函数说明
static getDerivedStateFromError(error)在后代组件抛出错误后调用。返回一个对象来更新 state,用于渲染降级 UI(如错误提示)。
componentDidCatch(error, info)在后代组件出错后调用。适合记录错误日志。

函数组件中的“生命周期”

函数组件没有传统生命周期方法,但通过 useEffect Hook 可以模拟所有生命周期行为:

import { useEffect, useState } from 'react';

function MyComponent({ userId }) {
  const [data, setData] = useState(null);

  // 模拟 componentDidMount + componentDidUpdate
  useEffect(() => {
    // 挂载后和更新时执行(类似 componentDidMount 和 componentDidUpdate)
    fetchData(userId).then(setData);

    // 清理函数(模拟 componentWillUnmount)
    return () => {
      // 清理副作用,如取消请求
    };
  }, [userId]); // 依赖数组:仅当 userId 变化时重新执行

  // 模拟 componentDidMount
  useEffect(() => {
    // 只在挂载后执行一次
    console.log('组件已挂载');
  }, []); // 空依赖数组

  return <div>{data}</div>;
}

总结

阶段推荐使用的生命周期函数
挂载constructor, getDerivedStateFromProps, render, componentDidMount
更新getDerivedStateFromProps, shouldComponentUpdate, render, getSnapshotBeforeUpdate, componentDidUpdate
卸载componentWillUnmount
错误处理getDerivedStateFromError, componentDidCatch

核心要点

  • 优先使用 getDerivedStateFromPropsgetSnapshotBeforeUpdate 替代旧的 UNSAFE_* 方法。
  • useEffect 是函数组件中管理副作用和生命周期逻辑的现代方式。
  • 始终在 componentWillUnmount 中清理副作用,防止内存泄漏。
THE END
喜欢就支持一下吧
点赞13 分享