React Hooks总览

总览

hooks 功能分类具体 hooks具体功能React v18新特性跨端支持
数据更新驱动useState定义要在页面中渲染的数据
useReducer定义要在页面中渲染的数据,且这个数据有多种处理逻辑
useSyncExternalStoreconcurrent 模式下,订阅外部 store 的行为,触发更新
useTransitionconcurrent 模式下,在不阻塞 UI 的情况下来更新状态
useDeferredValueconcurrent 模式下,延迟更新 UI 的某些部分
执行副作用useEffect异步状态下,视图更新后,执行副作用
useLayoutEffect同步状态下,视图更新前,执行副作用
useInsertionEffect用于处理 CSS-in-JS 缺陷问题
状态获取与传递useContext接收祖先组件的 context 传递的信息
useRef存储一个不需要渲染的值
useImperativeHandle配合 forwardRef 将子组件的 ref 传递给父组件
状态派生与保存useMemo缓存结果
useCallback缓存函数
工具 hooksuseId生成唯一的 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)

注意事项:

  1. 在函数组件一次执行上下文中,state 的值是固定不变的
  2. 如果两次 setState 传入相同的 state 值,那么组件就不会更新
  3. 当触发 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>)
}

注意:

  1. getSnapshot 返回的 store 快照必须是不可变

    如果底层 store 有可变数据,要在数据改变时返回一个新的不可变快照;否则,返回上次缓存的快照。

  2. 如果在重新渲染时传入一个不同的 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>)
}

注意:

  1. 只有在可以访问该状态的 set 函数时,才能将更新包装为转换状态

    如果想响应某个 prop 或自定义 Hook 值启动转换,请尝试使用 useDeferredValue

  2. 传递给 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。

注意:

  1. 不应在循环或者条件语句中调用 useCallback
  2. 应该仅仅把 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?)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/69651.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hive anti join 的几种写法

t_a 表的记录如下 c1 | :———— | a | b | c | 生成 SQL 如下&#xff1a; create table t_a(c1 string); insert into t_a values("a"),("b"),("c");t_b 表的记录如下 c1bm 生成 SQL 如下&#xff1a; create table t_b(c1 string); in…

Java低代码开发:jvs-list(列表引擎)功能(一)配置说明

在低代码开发平台中&#xff0c;列表页是一个用于显示数据列表的页面。它通常用于展示数据库中的多条记录&#xff0c;并提供搜索、排序和筛选等功能&#xff0c;以方便用户对数据进行查找和浏览。 jvs-list是jvs快速开发平台的列表页的配置引擎&#xff0c;它和普通的crud 具…

什么是SpringCloud Eureka服务注册与发现

&#x1f600;前言 本篇博文是关于SpringCloud Eureka 介绍&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&…

CS420 课程笔记 P4 - 以16进制形态编辑游戏文件

文章目录 IntroductionFinding save filesStringsUnicodeExample!Value searchHealth searchConclusion Introduction 这节课我们将学习编辑十六进制&#xff0c;主要用于编辑保存文件&#xff0c;但十六进制编辑涉及的技能可以很好地转移到&#xff1a; Save file editingRe…

【go-zero】使用自带Redis方法

yaml配置文件 RedisS:Host: Type: Pass: config增加 RedisS struct {Host stringType stringPass string}svc文件 type * struct {RedisClient *redis.Redis } func *(c config.Config) * {sqlConn : sqlx.NewMysql(c.DB.DataSource)return &*{RedisClient: redis.New(c…

linux配置网络的几种常用方法

linux配置ip地址有多种不同的方法&#xff0c;大家可以根据自己的需要来使用不同的方法配置ip地址。 方法一 ifconfig命令 使用 ifconfig 命令配置 IP 地址ifconfig 命令用于查看和配置网络接口&#xff0c; 可以使用该命令为网络接口配置 IP 地址。假设需要配置 eth0 网卡的…

Flutter实现CombineExecutor进行多个异步分组监听,监听第一个异步执行的开始和最后一个异步执行结束时机。

1.场景 我们在调用接口时&#xff0c;很多时候会同时调用多个接口&#xff0c;接口都是异步执行&#xff0c;我们很难知道调用的多个接口哪个会最后执行完成&#xff0c;我们有时候需要对最后一个接口执行完成的时机监听&#xff0c;所以基于该需求&#xff0c;设计了CombineE…

Shell 运算符及语法结构

目录 一、Shell运算符 1.1 表达式expr 1.2 运算操作 1.3 操作实例 二、Shell条件判断 2.1 基本语法 2.2 值、权限、类型、多条件判断 三、Shell流程控制 3.1 if 流程语法 3.2 case 流程语法 3.3 for 流程语法 3.4 内部运算符 3.5 while循环流程语法 四、Shell读…

TOOLLLM: FACILITATING LARGE LANGUAGE MODELS TO MASTER 16000+ REAL-WORLD APIS

本文是LLM系列的文章之一&#xff0c;针对《TOOLLLM: FACILITATING LARGE LANGUAGE MODELS TO MASTER 16000 REAL-WORLD APIS》的翻译。 TOOLLLMs&#xff1a;让大模型掌握16000的真实世界APIs 摘要1 引言2 数据集构建3 实验4 相关工作5 结论 摘要 尽管开源大型语言模型&…

前端图形图像的框架

前端图形图像方面有许多强大的框架和库&#xff0c;使得开发者能够更容易地创建丰富的视觉效果和复杂的图形应用。下面列举了一些主要的框架和库&#xff1a; 1. Three.js Three.js 是一款运行在浏览器中的 3D 引擎&#xff0c;你可以用它创建各种三维场景&#xff0c;包括了相…

如何将两个pdf合并成一个?pdf合并技巧分享

在日常工作过程当中&#xff0c;我们经常需要处理一些文件&#xff0c;而文件的处理往往是琐碎的&#xff0c;想要提高工作效率&#xff0c;需要选择一些合适的方法&#xff0c;并掌握一定的技巧&#xff0c;那么&#xff0c;如何将两个pdf合并成一个?pdf合并技巧有哪些呢?接…

java实现状态模式

状态模式是一种行为设计模式&#xff0c;它允许对象在内部状态改变时改变其行为。在状态模式中&#xff0c;对象将其行为委托给表示不同状态的状态对象&#xff0c;这些状态对象负责管理其行为。以下是在 Java 中实现状态模式的一般步骤&#xff1a; 创建一个状态接口&#xff…

AFG EDI 解决方案

AFG一直是汽车行业出境物流的专家&#xff0c;不仅运输汽车&#xff0c;同时也提供模块化IT解决方案&#xff0c;用于接收、控制、互联以及整个车辆调度过程的可视化和监控。 对于物流行业而言&#xff0c;如果已经确定了供应链整合的目标&#xff0c;但却没有明确的计划及足够…

【线上问题】很抱歉,如果没有 JavaScript 支持,将不能正常工作

目录 一、问题说明二、解决方式 一、问题说明 1.修改了nginx的配置 2.postman调用接口正常&#xff0c;浏览器访问接口200&#xff0c;但无数据 3.浏览器访问&#xff0c;nginx没有访问记录&#xff0c;接口请求到不了应用服务 4.原因不祥 二、解决方式 1.清理了浏览器缓存

mac下配置JDK环境

一、下载安装 下载地址&#xff1a;Java Downloads | Oracle&#xff0c;选择适用于Mac OS的JDK版本&#xff0c;点击下载即可。 下载完之后&#xff0c;直接安装&#xff1a; 安装过程非常简单&#xff0c;按“继续”按钮一直下一步即可。 二、配置环境变量 上一步骤&#x…

c++线程

pthread(部分内容来自菜鸟教程) 创建线程 创建一个 POSIX 线程&#xff1a; #include <pthread.h> pthread_create (thread, attr, start_routine, arg) pthread_create 创建一个新的线程&#xff0c;并让它可执行。 参数&#xff1a; thread &#xff1a;指向线程标…

Opencv 图像金字塔----高斯和拉普拉斯

原文&#xff1a;图像金字塔----高斯和拉普拉斯 图像金字塔是图像中多尺度表达的一种&#xff0c;最初用于机器视觉和图像压缩&#xff0c;最主要用于图像的分割、融合。 高斯金字塔 ( Gaussian pyramid): 高斯金字塔是由底部的最大分辨率图像逐次向下采样得到的一系列图像…

基于docker快速搭建facechain环境

前言 最近facechain比较火&#xff0c;之前在huggingface试过&#xff0c;在SD的落地场景上提供了思路。 这两天刚拿到一台RTX3090的服务器&#xff0c;在本地部署也遇到了两个问题&#xff0c;给大家分享一下。 一、facechain是什么&#xff1f; 官方是这样说的&#xff1a…

(九)mmdetection源码解读:训练过程中训练数据的调用DataLoader

目录 一、DataLoader创建过程中二、利用实例化data_loaders进行训练 一、DataLoader创建过程中 在训练过程train_detector函数中调用build_dataloader函数 train_detector(model, datasets, cfg, distributedFalse, validateTrue) #train_detector函数中 data_loaders [buil…

# 磁盘引导方式相关知识之BIOS、msdos、MBR、UEFI、gpt、esp、csm

磁盘引导方式相关知识之BIOS、msdos、MBR、UEFI、gpt、esp、csm 磁盘、分区、引导等知识经常似懂非懂&#xff0c;不能完全说清楚&#xff0c;梳理下&#xff1a; 序号主板芯片引导方式支持的磁盘分区表类型支持的磁盘分区表格式对应引导位置备注1BIOS传统方式&#xff08;俗…