React中类组件的生命周期

发布于:2025-04-03 ⋅ 阅读:(34) ⋅ 点赞:(0)

React 的生命周期指的是组件在创建、更新和销毁的整个过程。在 React 的类组件中,生命周期分为三个主要阶段:

  1. 挂载(Mounting)
  2. 更新(Updating)
  3. 卸载(Unmounting)

如果使用的是函数组件,生命周期是通过 useEffect 以及其他 Hooks 来管理的。


1. 挂载阶段(Mounting)

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

在类组件中,会触发以下方法:

  • constructor()
  • static getDerivedStateFromProps(props, state)
  • render()
  • componentDidMount()

详细介绍:

  • constructor(props)

    • 组件初始化时调用,用于设置初始状态 state 或绑定 this
    • ⚠️ 不要在这里执行异步操作,适合用于基本的初始化。
  • static getDerivedStateFromProps(props, state)

    • render 之前触发,用于根据 props 更新 state,但不常用
    • ⚠️ 这是一个静态方法,不能使用 this
  • render()

    • 组件渲染 UI,必须是纯函数,不能有副作用(如异步请求)。
  • componentDidMount()

    • 组件挂载后调用,通常用于发送网络请求、订阅事件、操作 DOM 等。
    • 适合执行副作用操作(如 setTimeoutsetInterval 等)。
    componentDidMount() {
      fetch("/api/data")
        .then(response => response.json())
        .then(data => this.setState({ data }));
    }
    

2. 更新阶段(Updating)

组件的 stateprops 发生变化时,触发更新。

会调用以下方法:

  • static getDerivedStateFromProps(props, state)
  • shouldComponentUpdate(nextProps, nextState)
  • render()
  • getSnapshotBeforeUpdate(prevProps, prevState)
  • componentDidUpdate(prevProps, prevState, snapshot)

详细介绍:

  • shouldComponentUpdate(nextProps, nextState)

    • 返回 true 组件才会重新渲染,false 则阻止更新,提高性能。
    • 适用于优化性能,防止不必要的重渲染。
  • render()

    • UI 重新渲染。
  • getSnapshotBeforeUpdate(prevProps, prevState)

    • 组件更新前的“快照”,常用于获取 DOM 变化前的信息(如滚动位置)。
    • 返回值会传递给 componentDidUpdate()
  • componentDidUpdate(prevProps, prevState, snapshot)

    • 组件更新完成后执行,适合发送异步请求、更新 DOM
    • ⚠️ 需要注意避免死循环!
    • 例如:
      componentDidUpdate(prevProps) {
        if (this.props.userId !== prevProps.userId) {
          this.fetchUserData();
        }
      }
      

3. 卸载阶段(Unmounting)

组件被从 DOM 中移除时触发。

只有一个方法:

  • componentWillUnmount()

详细介绍:

  • componentWillUnmount()

    • 组件销毁前调用,适用于清理副作用,如:
      • 清除 setIntervalsetTimeout
      • 取消 API 请求
      • 移除事件监听
    componentWillUnmount() {
      clearInterval(this.timer);
    }
    

⚛️ 在函数组件中,如何使用生命周期?

React 提供了 useEffect 来代替生命周期方法:

import { useEffect, useState } from "react";

function Example() {
  const [count, setCount] = useState(0);

  // 相当于 componentDidMount + componentDidUpdate
  useEffect(() => {
    console.log("组件挂载或更新了!");
    return () => {
      console.log("组件即将卸载!");
    };
  }, [count]); // 只有 count 变化时才会触发

  return <button onClick={() => setCount(count + 1)}>点击 {count}</button>;
}
  • useEffect(() => {}, []):只在组件挂载时运行(等价于 componentDidMount)。
  • useEffect(() => {}, [变量]):当 变量 变化时运行(等价于 componentDidUpdate)。
  • useEffect(() => { return () => {} }, []):组件卸载时运行(等价于 componentWillUnmount)。

前端哪些功能需要关注生命周期?

(一些涉及到内存泄漏的问题)

  1. 网络请求
  • componentDidMount() / useEffect(() => {}, [])
    • 组件加载时请求数据,如用户信息、列表数据。
  1. 事件监听
  • componentDidMount() / useEffect(() => {... return () => {...} }, [])

    • 监听键盘事件、窗口大小变化。
    • componentWillUnmount() 中移除监听 避免内存泄漏。
    useEffect(() => {
      window.addEventListener("resize", handleResize);
      return () => window.removeEventListener("resize", handleResize);
    }, []);
    
  1. 定时器
  • componentDidMount() / useEffect(() => {... return () => {...} }, [])
    • setInterval / setTimeout 需要在 componentWillUnmount() 里清除。
  1. DOM 操作
  • useEffect(() => {}, [])
    • 获取滚动位置、测量元素大小。
  1. 性能优化
  • shouldComponentUpdate() / React.memo()
    • 防止组件不必要的重新渲染。

总结

生命周期阶段 类组件方法 函数组件 Hook
挂载 componentDidMount() useEffect(() => {...}, [])
更新 componentDidUpdate(prevProps, prevState) useEffect(() => {...}, [依赖])
卸载 componentWillUnmount() useEffect(() => { return () => {...} }, [])

如果你用的是函数组件,大部分生命周期操作都可以通过 useEffect 处理。