React 生命周期函数详解

news/2025/2/10 15:23:30/

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/news/1570894.html

相关文章

【深度学习】利用Java DL4J 训练金融投资组合模型

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程,高并发设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s…

【Spring】Spring MVC入门(一)

目录 ​前言 什么是Spring Web MVC&#xff1f; 什么是MVC 什么是Spring MVC Spring MVC和Spring Boot的区别 什么是Spring Boot 关系和区别 学习Spring MVC 注解学习 SpringBootApplication RestController RequestMapping RequestMapping的使用 RequestMapping…

大模型应用与实战:专栏概要与内容目录

文章目录 大模型应用与实战&#x1f4da; 核心内容模块一、大模型推理与部署1.1 推理框架应用实践1.2 框架源码深度解析1.3 高并发部署优化1.4 国产化平台适配 二、Agent框架专题2.1 Langchain系列2.2 Qwen-Agent系列2.3 Dify应用实践2.4 框架对比与迁移 三、微调技术研究3.1 微…

Javascript包管理工具——NPM常见内容

常见的npm相关知识点&#xff0c;比如包管理、版本控制、命令使用、依赖管理等等。 首先&#xff0c;我得回忆自己面试时遇到的npm问题&#xff0c;或者网上常见的考点。比如npm是什么&#xff0c;package.json的作用&#xff0c;依赖类型&#xff0c;版本控制符号&#xff0c;…

面试准备——Java理论高级【笔试,面试的核心重点】

集合框架 Java集合框架是面试中的重中之重&#xff0c;尤其是对List、Set、Map的实现类及其底层原理的考察。 1. List ArrayList&#xff1a; 底层是动态数组&#xff0c;支持随机访问&#xff08;通过索引&#xff09;&#xff0c;时间复杂度为O(1)。插入和删除元素时&#…

排序合集(一)

以下是更完善和人性化的版本&#xff0c;增加了一些细节和解释&#xff0c;同时让内容更易读&#xff1a; 一、直接插入排序 (Insertion Sort) 基本思想 直接插入排序是一种简单直观的排序算法&#xff0c;就像我们打扑克牌时的操作&#xff1a;每次摸到一张牌&#xff0c;都…

ollama linux下载

实验室服务器&#xff08;A6000&#xff09;执行curl -fsSL https://ollama.com/install.sh | sh太慢了。 而sudo snap install ollama&#xff0c;容易爆cudalibrt.so12无法正常使用的bug。 发现 https://www.modelscope.cn/models/modelscope/ollama-linux 使用modelscope进…

Apache Kafka:高吞吐分布式流平台的深度解析

引言&#xff1a;流数据时代的挑战 在实时推荐、物联网数据处理、金融交易监控等场景中&#xff0c;传统消息队列面临三大核心挑战&#xff1a; 海量数据吞吐&#xff1a;日均千亿级消息处理需求 超低延迟要求&#xff1a;毫秒级端到端传递延迟 数据持久保障&#xff1a;故障…