当前位置: 首页 > news >正文

React 类生命周期 和 React Hooks 比对

React生命周期总结(旧、新生命周期以及Hooks)

理解什么是生命周期?
当我们使用各种框架开发程序时,当这个框架启动、程序刚运行时、各个页面之间的交互、数据渲染到页面上面、程序运行结束,应当会有个闭环的操作,而在这个环的起点和终点之间的各个节点,框架给给定一些特定函数供我们自行调用,方便我们执行一些操作,这便是生命周期。react也是如此

react有哪些生命周期函数和作用

类组件中的生命周期:

类组件的生命周期主要分为三个阶段:初始化阶段、更新阶段、卸载阶段

初始化阶段:也成组件挂载阶段,这个阶段会执行初次加载组件到第一次渲染到界面上的一系列钩子函数,用于初始化状态和绑定方法。
执行流程为:constructor->componentWillMount->render->componentDidMount

constructor:这是一个构造器,这里面可以接收一个父组件传来的props然后初始化state值 用于初始化值和方法
componentWillMount: 组件将要挂载,render之前会执行这个函数,也就说会在渲染浏览器dom之前执行这个函数,无实际用处
render:常用且重要的钩子函数之一。render执行完后便会将html标签及自定义的函数等这些语句对应渲染到浏览器上面
componentDidMount:组件挂载完毕后立即执行,可以操作DOM 适用于网络请求、数据获取、订阅等副作用

更新阶段:什么时候会执行更新阶段这一系列的钩子函数呢,那自然是我们在更新了state值的时候或者是接收到父组件props值的时
常规流程是:componentWillReceiveProps->shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate

componentWillReceiveProps:当子组件收到父组件传过来的props,会执行这个函数
shouldComponentUpdate:当更新state值的时会执行这个函数,适用于控制组件是否需要重新渲染。返回 false 可阻止更新,优化性能
componentWillUpdate:里面会有两个参数nextProps, nextState,这是将要渲染的props和state的值,为即将发生的重新渲染做准备
render: 和初始化时候执行的那个render一样,只是这里是更新值的,所以dom节点会重新更新一下。
componentDidUpdate: 组件更新完毕执行的钩子函数。适合执行 DOM 操作或网络请求

卸载阶段:当组件卸载时执行的钩子函数,这里只有一个,那就是componentWillUnmount

componentWillUnmount:组件卸载前调用。 用于清理定时器、取消网络请求、移除订阅等

错误处理:

getDerivedStateFromError:后代组件抛出错误后调用,返回一个 state 更新
componentDidCatch:捕获后代组件的错误,可用于记录错误信息

React17版本之后,废除了 componentWillMount、componentWillReceiveProps、componentWillUpdate 这个三个钩子函数,取而代之的是
getDerivedStateFromProps,其实是把这三个钩子函数融入到这一个钩子函数中,同时还新增了一个钩子函数 getSnapshotBeforeUpdate
新版生命周期执行顺序

getDerivedStateFromProps:返回一个对象来更新 state,或返回 null 不更新
getSnapshotBeforeUpdate:在 DOM 更新前捕获一些信息(如滚动位置)

挂载阶段:constructor->getDerivedStateFromProps->render->componentDidMount
更新阶段:getDerivedStateFromProps->shouldComponentUpdate->getSnapshotBeforeUpdate->render->componentDidUpdate
卸载阶段:componentWillUnmount

React Hooks: React Hooks 提供了一种更简洁的方式来管理函数组件的状态和副作用,同时也能模拟类组件中的生命周期方法

基础生命周期对照:

1、constructor → useState/useReducer

// 类组件
constructor(props) {super(props);this.state = { count: 0 };
}// 函数组件
const [count, setCount] = useState(0);

2、componentDidMount → useEffect 空依赖数组

// 类组件
componentDidMount() {console.log('组件已挂载');// 初始化操作
}// 函数组件
useEffect(() => {console.log('组件已挂载');// 初始化操作
}, []); // 空数组表示只在挂载时执行

3、componentDidUpdate → useEffect 带依赖

// 类组件
componentDidUpdate(prevProps, prevState) {if (this.state.count !== prevState.count) {console.log('count 已更新');}
}// 函数组件
useEffect(() => {console.log('count 已更新:', count);
}, [count]); // 只在 count 变化时执行

4、componentWillUnmount → useEffect 的清理函数

// 类组件
componentWillUnmount() {console.log('组件即将卸载');// 清理操作
}// 函数组件
useEffect(() => {return () => {console.log('组件即将卸载');// 清理操作};
}, []);

高级生命周期对应关系

1、shouldComponentUpdate → React.memo 或 useMemo

// 类组件
shouldComponentUpdate(nextProps, nextState) {return nextProps.value !== this.props.value;
}// 函数组件
const MyComponent = React.memo(function MyComponent(props) {/* 只在 props 变化时重新渲染 */
});// 或者使用 useMemo 优化部分渲染
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

2、getDerivedStateFromProps → useState + useEffect

// 类组件
static getDerivedStateFromProps(props, state) {if (props.value !== state.prevValue) {return {derivedData: props.value * 2,prevValue: props.value};}return null;
}// 函数组件
function MyComponent({ value }) {const [derivedData, setDerivedData] = useState(value * 2);const [prevValue, setPrevValue] = useState(value);if (value !== prevValue) {setDerivedData(value * 2);setPrevValue(value);}// 或者使用 useEffectuseEffect(() => {setDerivedData(value * 2);}, [value]);
}

3、getSnapshotBeforeUpdate 和 componentDidUpdate → useLayoutEffect

// 类组件
getSnapshotBeforeUpdate(prevProps, prevState) {if (prevProps.list.length < this.props.list.length) {return this.listRef.scrollHeight;}return null;
}componentDidUpdate(prevProps, prevState, snapshot) {if (snapshot !== null) {this.listRef.scrollTop += this.listRef.scrollHeight - snapshot;}
}// 函数组件
const listRef = useRef();useLayoutEffect(() => {if (listRef.current) {const { scrollHeight, scrollTop, clientHeight } = listRef.current;if (scrollTop + clientHeight === scrollHeight) {// 自动滚动到底部listRef.current.scrollTop = scrollHeight;}}
}, [list]); // 依赖列表数据

完整的生命周期案例

import React, { useState, useEffect, useRef, useLayoutEffect } from 'react';function LifecycleHooksExample({ initialCount }) {// 对应 constructor 和 stateconst [count, setCount] = useState(initialCount);const [prevCount, setPrevCount] = useState(null);const [data, setData] = useState(null);const [isLoading, setIsLoading] = useState(false);const timerRef = useRef();const divRef = useRef();// 对应 getDerivedStateFromPropsif (initialCount !== prevCount) {setCount(initialCount);setPrevCount(initialCount);}// 对应 componentDidMountuseEffect(() => {console.log('组件已挂载');fetchData();// 设置定时器timerRef.current = setInterval(() => {console.log('定时器运行中...');}, 1000);// 对应 componentWillUnmount 的清理函数return () => {console.log('组件即将卸载');clearInterval(timerRef.current);};}, []);// 对应 componentDidUpdate 特定 state/props 变化useEffect(() => {if (count > 10) {console.log('count 大于 10');}}, [count]);// 对应 getSnapshotBeforeUpdate + componentDidUpdateuseLayoutEffect(() => {if (divRef.current) {console.log('DOM 已更新,可以获取最新布局信息');console.log('div 高度:', divRef.current.clientHeight);}});const fetchData = async () => {setIsLoading(true);try {const response = await fetch('https://api.example.com/data');const result = await response.json();setData(result);} catch (error) {console.error('获取数据失败:', error);} finally {setIsLoading(false);}};const increment = () => {setCount(c => c + 1);};return (<div ref={divRef}><h2>生命周期 Hooks 示例</h2><p>当前计数: {count}</p><button onClick={increment}>增加</button>{isLoading ? (<p>加载中...</p>) : (data && <pre>{JSON.stringify(data, null, 2)}</pre>)}</div>);
}
http://www.dtcms.com/a/355219.html

相关文章:

  • 算力沸腾时代,如何保持“冷静”?国鑫液冷SY4108G-G4解锁AI服务器的“绿色空调”!
  • 第五章:Go运行时、内存管理与性能优化之性能分析与pprof工具
  • 配置windows下apache+PHP环境
  • 前端技术之---复制文本
  • docker安装kafka、zookeeper详细步骤
  • 【TEC045-KIT】基于复旦微 FMQL45T900 的全国产化 ARM 开发套件
  • COLMAP 和 SFM的关系是什么?
  • 微服务即时通信系统(十三)--- 项目部署
  • 第十七章 Java基础-常用API-System
  • ArkTS 与 TypeScript 的关系及鸿蒙开发常见错误案例
  • Upload Symbols Failed
  • 万字详解架构设计:业务架构、应用架构、数据架构、技术架构、单体、分布式、微服务都是什么?
  • 只用三招,无招重启钉钉
  • Video Ocean 接入 GPT-5
  • GeoScene Maps 开发-核心地图-标记点管理-用户交互弹窗
  • 大白话拆解力扣算法 HOT 100 - 哈希/双指针/滑动窗口
  • Mac Pro M4芯片 安装 VMware Fusion 和 windows
  • Vue Router 路由守卫详解与面试指南
  • 实体门店怎么利用小程序做好分销
  • 目标检测领域基本概念
  • 【Python】QT(PySide2、PyQt5):Qt Designer,VS Code使用designer,可能的报错
  • 发那科机器人弧焊电源气体省气装置
  • esp32c2 at 请问通过HTTPS进行OTA升级的AT命令流程有吗?
  • 专项智能练习(多媒体概述)
  • 如果已经安装了electron的一个版本,再次使用命令npm install electron不指定electron版本时,会下载安装新版本么?
  • VS2022+QT6.7+Multimedia(捕获Windows音频数据,生成实时频谱)
  • Day16_【机器学习建模流程】
  • Python备份实战专栏第2/6篇:30分钟搭建企业级API认证系统,安全性吊打90%的方案
  • R语言贝叶斯方法在生态环境领域中的高阶技术应用
  • Mac 开发环境与配置操作速查表