React Hooks总览
总览
| hooks 功能分类 | 具体 hooks | 具体功能 | React v18新特性 | 跨端支持 |
|---|---|---|---|---|
| 数据更新驱动 | useState | 定义要在页面中渲染的数据 | ❌ | ✔ |
| useReducer | 定义要在页面中渲染的数据,且这个数据有多种处理逻辑 | ❌ | ✔ | |
| useSyncExternalStore | concurrent 模式下,订阅外部 store 的行为,触发更新 | ✔ | ❌ | |
| useTransition | concurrent 模式下,在不阻塞 UI 的情况下来更新状态 | ✔ | ❌ | |
| useDeferredValue | concurrent 模式下,延迟更新 UI 的某些部分 | ✔ | ❌ | |
| 执行副作用 | useEffect | 异步状态下,视图更新后,执行副作用 | ❌ | ✔ |
| useLayoutEffect | 同步状态下,视图更新前,执行副作用 | ❌ | ✔ | |
| useInsertionEffect | 用于处理 CSS-in-JS 缺陷问题 | ✔ | ❌ | |
| 状态获取与传递 | useContext | 接收祖先组件的 context 传递的信息 | ❌ | ✔ |
| useRef | 存储一个不需要渲染的值 | ❌ | ✔ | |
| useImperativeHandle | 配合 forwardRef 将子组件的 ref 传递给父组件 | ❌ | ✔ | |
| 状态派生与保存 | useMemo | 缓存结果 | ❌ | ✔ |
| useCallback | 缓存函数 | ❌ | ✔ | |
| 工具 hooks | useId | 生成唯一的 ID | ✔ | ❌ |
| useDebugValue | 在 React 开发者工具中为自定义 Hook 添加标签 | ❌ | ❌ |
数据更新驱动
useState
useState 允许向组件添加一个 状态变量。
/*** @param { any } initValue:初始值* @return { array } arr:状态信息state { any } 状态名setState { function } 修改状态的函数*/
const [state, setState] = useState(initValue)// 第一种方式:传入值
setState(newValue);// 第二种方式:传入函数
setState(preValue => newValue);
示例:
const [number, setNumber] = useState(0)// 第一种方式:传入值
setNumber(number + 1)// 第二种方式:传入函数
setNumber(number => number + 1)
注意事项:
- 在函数组件一次执行上下文中,state 的值是固定不变的
- 如果两次 setState 传入相同的 state 值,那么组件就不会更新
- 当触发 setState 在当前执行上下文中获取不到最新的 state,只有在下一次组件 render 中才能获取到
useReducer
useReducer 能够在无状态组件中运行的类似 redux 的功能 api 。
当对一个状态有多种处理逻辑时建议使用 useReducer。
/*** @param { function } reducer:处理函数* @param { any } initValue:初始值* @param { function } compareInitValueFn:计算初始值的函数,如果存在则初始值为 compareInitValueFn(initValue)* @return { array } arr:状态信息state { any } 状态名dispatchState { function } 派发状态的函数*/
const [state, dispatchState] = useReducer(stateReducer, initValue, compareInitValueFn?)
示例:
const numberReducer = (state, action) => {switch(action.type) {case 'add':return state + 1;case 'reduce':return state - 1;}
}
const [number, dispatchNumber] = useReducer(numberReducer, 0);dispatchNumber({type: 'add'
})
useSyncExternalStore
useSyncExternalStore 可以订阅外部 store。
/*** @param { function } subscribe:订阅函数* @param { function } getSnapshot:返回组件需要的 store 中的数据快照 带有记忆功能的选择器* @param { function } getServerSnapshot:用于 hydration 模式下的 getSnapshot* @return { any } snapshot:该 store 的当前快照*/
const snapshot = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)
示例:
import { combineReducers , createStore } from 'redux'/* number Reducer */
function numberReducer(state = 1, action) {switch(action.type) {case 'ADD':return state + 1case 'DEL':return state - 1default:return state}
}/* 注册reducer */
const rootReducer = combineReducers({ number: numberReducer })
/* 创建 store */
const store = createStore(rootReducer, { number: 1})function Index(){/* 订阅外部数据源 */const state = useSyncExternalStore(store.subscribe, () => store.getState().number)return (<div><button onClick={()=>store.dispatch({type:'ADD'})}>{ state }</button></div>)
}
注意:
getSnapshot 返回的 store 快照必须是不可变
如果底层 store 有可变数据,要在数据改变时返回一个新的不可变快照;否则,返回上次缓存的快照。
如果在重新渲染时传入一个不同的 subscribe 函数,React 会用新传入的 subscribe 函数重新订阅该 store
可以通过在组件外声明 subscribe 来避免。
useTransition
useTransition 可以在不阻塞 UI 的情况下来更新状态。
/*** @return { array } transitionInfo:转换状态信息isPending { boolean } 是否存在待处理的转换startTransition { function } 将状态由更新状态标记为转换状态@param { function } scope:作用域函数*/
const [isPending, startTransition] = useTransition()
示例:
export default function Index(){const [number, setNumber] = React.useState(0) // 需要立即响应的任务,立即更新任务const [count, setCount] = useState(0) // 不需要立即响应的任务,过渡任务const [isPending, startTransition] = useTransition() const btnClick = () => {setNumber(number + 1) // 立即更新startTransition(() => { // startTransition 里面的任务优先级低setCount(count + 1);})}return (<div><button onClick={()=>btnClick()}>{ count }</button></div>)
}
注意:
只有在可以访问该状态的
set函数时,才能将更新包装为转换状态如果想响应某个 prop 或自定义 Hook 值启动转换,请尝试使用 useDeferredValue
传递给 startTransition 的函数必须是同步的。
useDeferredValue
useDeferredValue 可以延迟更新 UI 的某些部分。
/*** @param { any } value:延迟更新的值* @return { any } deferredValue:延迟更新的值*/
const deferredValue = useDeferredValue(value)
示例:
export default function Index(){const [number, setNumber] = useState(1) // 需要立即响应的任务,立即更新任务const deferNumber = useDeferredValue(number) // 把状态延时更新,类似于过渡任务const btnClick = () => {setNumber(number + 1) // 立即更新}return (<div><button onClick={()=>btnClick()} >{ deferNumber }</button></div>)
}
- 在组件的初始渲染期间,返回的延迟值将与提供的值相同
- 但是在组件更新时,React 将会先尝试使用旧值进行重新渲染(因此将返回旧值)
- 然后再在后台使用新值进行另一个重新渲染(这时将返回更新后的值)
注意:应该向 useDeferredValue 传递原始值或在渲染之外创建的对象。
如果在渲染期间创建了一个新对象,并立即将其传递给 useDeferredValue,那么每次渲染时这个对象都会不同,这将导致后台不必要的重新渲染。
执行副作用
useEffect
useEffect 用于异步监听组件的 state 属性,在浏览器绘制后执行。
/*** @param { function } setup:回调函数,初始化执行一次,当监听的 state 改变时执行,返回一个当组件被销毁时执行的函数* @param { array } dependencies:要监听的 state,默认为所有 state,空数组表示不监听任何 state*/
useEffect(setup, dependencies?)
示例:
useEffect(() => {let timer = setInterval(() => {console.log(1)}, 1000)return () => {timer = null}
}, [])
可以把 useEffect 看作是以下三个生命周期的组合:
- componentDidMount():组件挂载完成执行 callback
- componentDidUpdate():监听的 state 变化执行 callback
- componentWillUnmount():组件将要销毁执行 callback 的返回函数
useLayoutEffect
useLayoutEffect 是 useEffect 的同步版本,并且是在浏览器绘制前执行,主要用于操作 DOM。
注意:useLayoutEffect callback 中代码执行会阻塞浏览器绘制
/*** @param { function } setup:回调函数,初始化执行一次,当监听的 state 改变时执行,返回一个当组件被销毁时执行的函数* @param { array } dependencies:要监听的 state,默认为所有 state,空数组表示不监听任何 state*/
useLayoutEffect(setup, dependencies?)
useInsertionEffect
useInsertionEffect 可以在布局副作用触发之前将元素插入到 DOM 中。
注意:useInsertionEffect 是为 CSS-in-JS 库的作者特意打造的。除非正在使用 CSS-in-JS 库并且需要注入样式,否则应该使用 useEffect 或者 useLayoutEffect。
/*** @param { function } setup:回调函数,初始化执行一次,当监听的 state 改变时执行,返回一个当组件被销毁时执行的函数* @param { array } dependencies:要监听的 state,默认为所有 state,空数组表示不监听任何 state*/
useInsertionEffect(setup, dependencies?)
状态获取与传递
useContext
useContext 用于接收祖先组件的 context 传递的信息。
/*** @param { context } context:context 容器* @return { any } value:祖先组件传递的 context*/
const value = useContext(context)
示例:
// 1、创建 context 容器
const NumberContext = createContext(null);// 2、祖先组件定义 Provider
function GrandFather() {return (<NumberContext.Provider value={1}><Father /></NumberContext.Provider>);
}// 3、父组件中使用子组件
function Father() {return (<Son></Son>)
}// 4、子组件中通过 useContext 接收祖先组件传递的数据
function Son() {const number = useContext(NumberContext);
}
useContext()总是在调用它的组件 上面 寻找最近的 provider。它向上搜索,不考虑 调用useContext()的组件中的 provider。
useRef
useRef 可以存储一个不需要渲染的值。
与 state 的区别:ref 的改变不会渲染,state 会
与普通对象的区别:ref 的值不会重置,普通对象会
/*** @param { any } initValue:初始值* @return { ref } ref:只有 current 属性的 ref 对象*/
const ref = useRef(initValue)
示例:
function Demo() {const divRef = useRef(null)return (<div ref={divRef}>ref节点</div>)
}
不要在 渲染期间 写入或者读取
ref.current。可以在 事件处理程序或者 effects 中读取和写入 ref。
useImperativeHandle
useImperativeHandle 配合 forwardRef 将子组件的 ref 传递给父组件。
/*** @param { ref } ref:forWardRef 渲染函数中获得的第二个参数* @param { function } createHandle:处理函数,返回值作为暴露给父组件的 ref 对象* @param { array } dependencies:依赖项*/
useImperativeHandle(ref, createHandle, dependencies?)
示例:
// 子组件
const Son = forwardRef((props, ref) => {const divRef = useRef(null)useImperativeHandle(ref, () => {return {sendData: () => {console.log(divRef.current)}}}, [])return <div ref={divRef}>子组件</div>
})
// 父组件
function Parent() {const sonRef = useRef(null)return <Son ref={sonRef}></Son>
}
状态派生与保存
useMemo
useMemo 在每次重新渲染的时候能够缓存计算的结果。
/*** @param { function } calculateValue:要缓存计算值的函数,返回值作为缓存值* @param { array } dependencies:依赖项数组* @return { any } cachedValue:缓存值(calculateValue 返回的值)*/
const cachedValue = useMemo(calculateValue, dependencies)
- cachedValue 初次为不带参数调用 calculateValue 的返回值
- 后续如果依赖项没有变,就返回上次缓存的值;否则将再次调用 calculateValue,并返回最新结果
注意:应该仅仅把 useMemo 作为性能优化的手段
useCallback
useCallback 允许在多次渲染中缓存函数。
/*** @param { function } fn:想要缓存的函数* @param { array } dependencies:依赖项数组* @return { function } cachedFn:缓存的函数*/
const cachedFn = useCallback(fn, dependencies)
- 在初次渲染时,useCallback 返回你已经传入的 fn 函数
- 在之后的渲染中, 如果依赖没有改变,useCallback 返回上一次渲染中缓存的 fn 函数;否则返回这一次渲染传入的 fn。
注意:
- 不应在循环或者条件语句中调用 useCallback
- 应该仅仅把 useMemo 作为性能优化的手段
工具 hooks
useId
useId 可以生成传递给无障碍属性的唯一 ID。
/*** @return { string } id:唯一的字符串 ID*/
const id = useId()
注意:不要使用 useId 来生成列表中的 key。
useDebugValue
useDebugValue 可以在 React 开发工具 中为自定义 Hook 添加标签。
/*** @param { any } value:在 React 开发工具中显示的值* @param { function } format:如果传入,则值为将 value 作为参数调用 format 返回的值;否则值为 value*/
useDebugValue(value, format?)
相关文章:
React Hooks总览
总览 hooks 功能分类具体 hooks具体功能React v18新特性跨端支持数据更新驱动useState定义要在页面中渲染的数据❌✔useReducer定义要在页面中渲染的数据,且这个数据有多种处理逻辑❌✔useSyncExternalStoreconcurrent 模式下,订阅外部 store 的行为&am…...
风向变了!智能汽车何以「降本」
随着软件定义汽车的概念逐步落地,以及底盘、动力、座舱、智驾、车身等不同域(分布式或者混合式)的功能更新迭代和融合,汽车行业正在意识到:底层硬件架构重构的迫切性。 事实上,早在2016年,作为传…...
后端面试话术集锦第 十五 篇:java线程面试话术
这是后端面试集锦第十五篇博文——java线程面试话术❗❗❗ 1. 创建线程的方式 首先呢,Thread类本质上是实现了Runnable接口,代表一个线程的实例。 所以,我们可以编写一个类,继承Thread类,或者直接实现Runnable接口。然后,再重写下~run方法就行了。启动线程的方式就是调…...
cocos creator配置终端调试
在launch.json里添加"preLaunchTask":“CocosCreator compile” 在cocos creator里选择开发者,visual studio code工作流,选择添加编译任务。 添加 settings.json {"files.exclude":{"**/.git": true,"**/.DS_Sto…...
达梦类型转换问题-float转换为varchar
表结构 CREATE TABLE "SYSDBA"."TABLE_2" ( "COLUMN_1" FLOAT, "COLUMN_2" NUMERIC(22,6)) STORAGE(ON "MAIN", CLUSTERBTR) ; 表数据: 查询,将numeric转换为float,再转换为varchar&…...
怎么用postman连接websocket
点击右侧栏的Collections,然后点击旁边的New,然后点击其中的WebSocket Request,然后输入Url,点击Connection,这里需要注意的是Url不能加上http://,因为这个不是http协议。...
需求分析入门
认识管理软件 什么是管理软件 管理软件就是用来辅助企业进行管理的软件,既包括对企业“人、财、物”相关的资产信息的管理,也包括对企业“供、产、销”相关的业务活动信息的管理。管理软件的重点在于管理信息的收集、流转,资源的共享、集成…...
攻防世界-php_rce
原题 解题思路 thinkPHP.0有漏洞,ThinkPHP5.x rec 漏洞分析与复现。本题就是利用漏洞查找。格式是: ?sindex/\think\app/invokefunction&functioncall_user_func_array&vars[0]system&vars[1][]命令。 ls查看文件没什么东西,r…...
最小生成树Kruskal、Prim算法C++
什么是最小生成树 连通图: 在无向图中,若从顶点v1到顶点v2有路径,则称顶点v1和顶点v2是连通的。如果图中任意一对顶点都是连通的,则称此图为连通图。 生成树: 一个连通图的最小连通子图称作为图的生成树。有n个顶点的…...
系统架构设计师-计算机系统基础知识(2)
目录 一、存储管理 1、页式存储 2、段式存储 3、段页式存储 二、磁盘管理 1、先来先服务FCFS 2、最短寻道时间优先SSTF 三、文件系统 1、文件基本概念 2、文件的类型: 3、索引文件结构 4、位示图 四、性能指标 五、性能设计 1、阿姆达尔定律 六、性能评估 1、…...
二叉树的介绍
写在前面: 二叉树是数据结构课程中非常重要的内容,我们针对二叉树的概念、性质以及类型展开详细介绍。 一、概念 二叉树(Binary Tree)是n(n>0)个结点的有限集合,该集合或者空集࿰…...
数据结构与算法复杂度介绍
目录 一、基本概念 二、时间复杂度 【2.1】时间复杂度概念 【2.2】大O的渐进表示法 【2.3】举例时间复杂度计算 三、空间复杂度 一、基本概念 数据结构:相互之间存在一种或者多种特定关系的数据元素的集合。在逻辑上可以分为线性结构,散列结构、树…...
CentOS 安装蒲公英
官方教程链接: https://service.oray.com/question/5063.html 教程使用的是2.3版本,官网下载的最新版是2.4,所以命令会有所不同 安装成功后, 任意路径下执行pgyvisitor,调出交互界面pgyvisitor login,登录…...
英语语法基础--思维导图
思维导图通常用于可视化和整理信息,而英文语法非常广泛且复杂,无法在一个简单的思维导图中完整表示。然而,我可以提供一个简化版本的英文语法思维导图,列出一些主要的语法概念和部分示例。 请注意,这只是一个基本的概…...
Android泛型详解
参考文献:https://pingfangx.github.io/java-tutorials/java/generics/types.html 1,什么是泛型? Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了 编译时类型安全检测机制, 该机制允许程序员在编译时检测到…...
C++信息学奥赛1178:成绩排序
#include<bits/stdc.h> using namespace std; int main(){int n;cin>>n; // 输入整数 n,表示数组的大小int arr[n]; // 创建大小为 n 的整型数组 arrstring brr[n]; // 创建大小为 n 的字符串数组 brrfor(int i0;i<n;i) cin>>brr[i]>>ar…...
【计算机视觉 | 目标检测】目标检测常用数据集及其介绍(七)
文章目录 一、Cops-Ref二、FAT (Falling Things)三、GEN1 Detection (Prophesee GEN1 Automotive Detection Dataset)四、RIT-18五、AGAR (Annotated Germs for Automated Recognition)六、EuroCity Persons七、Freiburg Groceries八、Lytro Illum九、PFN-PIC (PFN Picking Ins…...
100天精通Golang(基础入门篇)——第20天:Golang 接口 深度解析☞从基础到高级
🌷🍁 博主猫头虎🐅🐾 带您进入 Golang 语言的新世界✨✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文并茂…...
ESXi 6.7添加螃蟹2.5g网卡支持
安装了ESXi 6.7,结果机器两块网卡只能识别一块,然后想着不能让另一块浪费啊,开始折腾,看着网上都是找的驱动然后封装进iso,可是我已经装完了,怎么办,然后找到了下面解决方法 1.找驱动 下载RTL81…...
机器学习笔记之最优化理论与方法(四) 凸函数:定义与基本性质
机器学习笔记之最优化理论与方法——再回首:凸函数定义与基本性质 引言凸函数的定义严格凸函数凸函数的推论:凹函数 常见凸函数凸函数的基本性质几种保持函数凸性的运算凸集与凸函数之间的关联关系 引言 本节将介绍凸函数定义及其基本性质。 本文是关于…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
