React 生命周期函数详解

server/2025/2/9 11:28:15/

React 组件在其生命周期中有多个阶段,每个阶段都有特定的生命周期函数(Lifecycle Methods)。这些函数允许你在组件的不同阶段执行特定的操作。以下是 React 组件生命周期的主要阶段及其对应的生命周期函数,并结合了 React 16.3+ 的变化。


一、挂载阶段(Mounting)

在组件首次被挂载到 DOM 时会触发的一系列生命周期函数。

  • constructor(props)

    • 初始化组件的状态和绑定事件处理器。
    • 注意:尽量避免在此进行复杂的计算或副作用操作。
    constructor(props) {super(props);this.state = { count: 0 };this.handleClick = this.handleClick.bind(this); // 绑定事件处理器
    }
    
  • static getDerivedStateFromProps(nextProps, prevState)

    • 在组件挂载和更新之前调用,用于根据新的 props 更新 state。
    • 返回一个对象来更新 state,或者返回 null 表示不需要更新。
    static getDerivedStateFromProps(nextProps, prevState) {if (nextProps.value !== prevState.value) {return { value: nextProps.value };}return null;
    }
    
  • render()

    • 必须实现的方法,用于渲染组件的虚拟 DOM。
    • 不应该在这里进行副作用操作(如 API 调用、DOM 操作等)。
    render() {return <div>{this.state.count}</div>;
    }
    
  • componentDidMount()

    • 组件挂载完成后调用,通常用于发起网络请求、订阅事件等副作用操作。
    componentDidMount() {fetch('/api/data').then(response => this.setState({ data: response.data }));
    }
    

二、更新阶段(Updating)

当组件的 props 或 state 发生变化时,会触发一系列更新阶段的生命周期函数。

  • static getDerivedStateFromProps(nextProps, prevState)

    • 同挂载阶段的 getDerivedStateFromProps,用于根据新的 props 更新 state。
  • shouldComponentUpdate(nextProps, nextState)

    • 判断组件是否需要重新渲染。返回 false 可以阻止不必要的重新渲染,从而优化性能。
    shouldComponentUpdate(nextProps, nextState) {return nextState.count !== this.state.count;
    }
    
  • render()

    • 同挂载阶段的 render() 方法,用于渲染组件的虚拟 DOM。
  • getSnapshotBeforeUpdate(prevProps, prevState)

    • 在最新的渲染输出提交给 DOM 之前调用,可以捕获一些 DOM 信息(如滚动位置),以便在 componentDidUpdate 中使用。
    getSnapshotBeforeUpdate(prevProps, prevState) {if (prevProps.items.length < this.props.items.length) {return this.listRef.scrollHeight;}return null;
    }
    
  • componentDidUpdate(prevProps, prevState, snapshot)

    • 组件更新完成后调用,可以在此进行副作用操作(如网络请求、DOM 操作等)。
    componentDidUpdate(prevProps, prevState, snapshot) {if (snapshot !== null) {this.listRef.scrollTop = this.listRef.scrollHeight - snapshot;}
    }
    

三、卸载阶段(Unmounting)

当组件从 DOM 中卸载时会触发的生命周期函数。

  • componentWillUnmount()

    • 组件卸载和销毁之前立刻调用,通常用于清理工作,如取消网络请求、清除定时器、移除事件监听器等。
    componentWillUnmount() {clearInterval(this.timerID);this.subscription.remove();
    }
    

四、错误处理阶段(Error Handling)

当组件抛出错误时会触发的生命周期函数。

  • static getDerivedStateFromError(error)

    • 当子组件抛出错误时调用,用于更新 state 以便显示错误 UI。
    static getDerivedStateFromError(error) {return { hasError: true };
    }
    
  • componentDidCatch(error, info)

    • 当子组件抛出错误时调用,通常用于记录错误日志或上报错误。
    componentDidCatch(error, info) {logErrorToService(error, info);
    }
    

五、React 16.3+ 生命周期变化

随着 React 16.3+ 的发布,部分生命周期函数被废弃或新增了一些新的生命周期函数:

  • 废弃的生命周期

    • componentWillMount(建议使用 componentDidMount
    • componentWillReceiveProps(建议使用 static getDerivedStateFromProps
    • componentWillUpdate(建议使用 getSnapshotBeforeUpdate
  • 新增的生命周期

    • getDerivedStateFromProps:用于在挂载和更新前根据 props 更新 state。
    • getSnapshotBeforeUpdate:在最新的渲染输出提交给 DOM 之前调用,捕获一些 DOM 信息。

钩子函数(Hooks)

随着 React Hooks 的引入,许多类组件的生命周期方法可以通过钩子函数来实现:

  • useEffect

    • 相当于 componentDidMountcomponentDidUpdatecomponentWillUnmount 的组合。
    useEffect(() => {// 类似 componentDidMount 和 componentDidUpdatefetchData().then(data => setState({ data }));// 清理函数,类似 componentWillUnmountreturn () => {cleanup();};
    }, [props.userID]); // 依赖项数组
    
  • useLayoutEffect

    • 类似 useEffect,但在所有 DOM 变更之后同步调用,适用于需要同步执行的副作用操作。
  • useMemouseCallback

    • 用于性能优化,类似于 shouldComponentUpdate

总结

React 组件的生命周期分为三个主要阶段:挂载(Mounting)、更新(Updating)和卸载(Unmounting)。每个阶段都有相应的生命周期函数,帮助开发者在组件的不同生命周期中执行特定的操作。

  • 挂载阶段:初始化状态、渲染组件、发起数据请求等。
  • 更新阶段:判断是否需要重新渲染、捕获 DOM 信息、执行副作用操作等。
  • 卸载阶段:清理资源、取消订阅等。

通过合理使用这些生命周期函数,可以构建出更加健壮和高效的 React 应用程序。同时,现代 React 开发中推荐使用 Hooks 来替代类组件的生命周期方法,以简化代码并提高可维护性。

理解这些生命周期函数及其作用,不仅有助于编写高效且易于维护的 React 组件,还能更好地应对复杂的应用场景。


http://www.ppmy.cn/server/166209.html

相关文章

探秘数据结构之单链表:从原理到实战的深度解析

目录 一、链表的概念及结构 1.1 链表的独特定义 1.2 火车车厢式的形象类比 1.3 节点的结构体定义剖析 1.4 链表物理与逻辑结构的特性差异 二、单链表的实现 2.1 类型定义的优化策略 2.2 链表操作函数的声明框架 2.3 链表操作函数的实现细节 三、链表的分类 前言 …

ES6-代码编程风格(数组、函数)

1 数组 使用扩展运算符&#xff08;...&#xff09;复制数组。 const itemsCopy [...items]; 使用Array.from 方法将类似数组的对象转为数组。 const foo document.querySelectorAll(.foo); const nodes Array.from(foo); 2 函数 立即执行函数可以写成箭头函数的形式…

Maven的三种项目打包方式——pom,jar,war的区别

Maven 是一个强大的项目管理和构建工具&#xff0c;广泛应用于Java项目的构建和管理。Maven 支持多种打包方式&#xff0c;其中最常用的三种是 pom、jar 和 war。理解这三种打包方式的区别&#xff0c;对于正确配置和管理项目至关重要。本文将详细解释这三种打包方式的用途、特…

MR30分布式IO模块:驱动智能制造工厂的工业互联与高效控制新范式

在工业4.0与智能制造浪潮的推动下&#xff0c;传统制造业正经历着从“机械驱动”向“数据驱动”的深刻转型。作为工业数据连接领域的领军者&#xff0c;明达技术凭借其自主研发的MR30分布式IO模块&#xff0c;以创新的技术架构与卓越的性能表现&#xff0c;为全球制造企业构建了…

IDEA远程调试weblogic(docker部署)

1、 进入 /weblogic/CVE-2017-10271 文件夹&#xff0c;修改其中的 docker-compose.yml 文件&#xff0c; 将 8453 端口打开 2、 docker-compose up -d 编译镜像并启动容器 docker exec -it 3d /bin/bash 命令进入容器&#xff0c;使用 vi 修改文件 /root/Oracle/Middl…

vue 主子表加校验问题

1.在table绑定的data中将数据源加上form&#xff0c;要将tabel包含在form表单中才行 <el-table :data"form.procurementPlanDevicesList" :row-class-name"rowProcurementPlanDevicesIndex"selection-change"handleProcurementPlanDevicesSelecti…

人工智能-音乐创作(变分自编码器(VAE)、生成对抗网络(GAN)和Transformer架构)

以下分别为你提供使用变分自编码器&#xff08;VAE&#xff09;、生成对抗网络&#xff08;GAN&#xff09;和Transformer架构进行音乐创作的代码示例。这些示例基于PyTorch框架&#xff0c;并使用了一些简单的音乐表示方法&#xff0c;实际应用中可能需要根据具体的音乐数据和…

A股level2高频数据分析20250205

A股level2高频数据分析20250205 通过Level2的逐笔成交与委托记录&#xff0c;这种高精度的毫秒级数据能够洞察诸多重要信息&#xff0c;包括庄家目的、误导性行为&#xff0c;使所有交易操作透明化。这对于分析高手的交易策略极为有益&#xff0c;对机器学习的研究也极具价值&…