React hook 10种常见 Hook
React Hook是什么?
React官网是这么介绍的: Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
完全可选的 你无需重写任何已有代码就可以在一些组件中尝试 Hook。但是如果你不想,你不必现在就去学习或使用 Hook。
100% 向后兼容的 Hook 不包含任何破坏性改动。
现在可用 Hook 已发布于 v16.8.0。
没有计划从 React 中移除 class 你可以在本页底部的章节读到更多关于 Hook 的渐进策略。
Hook 不会影响你对 React 概念的理解 恰恰相反,Hook 为已知的 React 概念提供了更直接的 API:props, state,context,refs 以及生命周期。稍后我们将看到,Hook 还提供了一种更强大的方式来组合他们。
如果对react还不够了解建议先看下react官方文档,写写demo再来看文章,因为有的react基础的东西我就一笔带过不细说。
react 官方文档 https://zh-hans.reactjs.org/docs/hooks-state.html
React目前提供的Hook
hook 用途
useState 设置和改变state,代替原来的state和setState
useEffect 代替原来的生命周期,componentDidMount,componentDidUpdate 和 componentWillUnmount 的合并版
useLayoutEffect 与 useEffect 作用相同,但它会同步调用 effect
useMemo 控制组件更新条件,可根据状态变化控制方法执行,优化传值
useCallback useMemo优化传值,usecallback优化传的方法,是否更新
useRef 跟以前的ref,一样,只是更简洁了
useContext 上下文爷孙及更深组件传值
useReducer 代替原来redux里的reducer,配合useContext一起使用
useDebugValue 在 React 开发者工具中显示自定义 hook 的标签,调试使用。
useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。
1.useState
import React from 'react';
import './App.css';
//通常的class写法,改变状态
class App extends React.Component {constructor(props){super(props)this.state = {hook:'react hook 是真的好用啊'}}changehook = () => {this.setState({hook:'我改变了react hook 的值'})}render () {const { hook } = this.statereturn(<header className="App-header">{hook}<button onClick={this.changehook}>改变hook</button></header>)}
}
export {App}//函数式写法,改变状态
function App() {
//创建了一个叫hook的变量,sethook方法可以改变这个变量,初始值为‘react hook 是真的好用啊’const [hook, sethook] = useState("react hook 是真的好用啊");return ( <header className="App-header">{hook}{/**这里的变量和方法也是可以直接使用的 */}<button onClick={() => sethook("我改变了react hook 的值")}>改变hook</button></header>);
}
export {App}//箭头函数的函数写法,改变状态
export const App = props => {const [hook, sethook] = useState("react hook 是真的好用啊");return (<header className="App-header">{hook}<button onClick={() => sethook("我改变了react hook 的值")}>改变hook</button></header>);
};
使用方法备注在上面的demo中
看完上面useState的对比使用,一个小的demo结构更清晰,代码更简洁,更像写js代码,运用到项目中,那岂不是美滋滋。
2.useEffect & useLayoutEffect
useEffect代替原来的生命周期,componentDidMount,componentDidUpdate 和 componentWillUnmount 的合并版
useEffect( ()=>{ return ()=>{ } } , [ ])第一个参数,是函数,默认第一次渲染和更新时都会触发,默认自带一个return ,return一个函数表示可以再销毁之前可以处理些事情
第二个参数,数组【】,空的时候表示只执行一次,更新时不触发,里面的参数是什么,当参数变化时才会执行useEffect
useEffect可以多次使用,按照先后顺序执行
useLayoutEffect 强制useeffect的执行为同步,并且先执行useLayoutEffect内部的函数
import React, { useState, useEffect, useLayoutEffect } from 'react';//箭头函数的写法,改变状态
const UseEffect = (props) => {//创建了一个叫hook的变量,sethook方法可以改变这个变量,初始值为‘react hook 是真的好用啊’const [ hook, sethook ] = useState('react hook 是真的好用啊');const [ name ] = useState('baby张');return (<header className="UseEffect-header"><h3>UseEffect</h3><Child hook={hook} name={name} />{/**上面的变量和下面方法也是可以直接使用的 */}<button onClick={() => sethook('我改变了react hook 的值' + new Date().getTime())}>改变hook</button></header>);
};const Child = (props) => {const [ newhook, setnewhook ] = useState(props.hook);//这样写可以代替以前的componentDidMount,第二个参数为空数组,表示该useEffect只执行一次useEffect(() => {console.log('first componentDidMount');}, []);//第二个参数,数组里是hook,当hook变化时,useEffect会触发,当hook变化时,先销毁再执行第一个函数。useEffect(() => {setnewhook(props.hook + '222222222');console.log('useEffect');return () => {console.log('componentWillUnmount ');};},[ props.hook ]);//useLayoutEffect 强制useeffect的执行为同步,并且先执行useLayoutEffect内部的函数useLayoutEffect(() => {console.log('useLayoutEffect');return () => {console.log('useLayoutEffect componentWillUnmount');};},[ props.hook ]);return (<div><p>{props.name}</p>{newhook}</div>);
};export default UseEffect;
3.useMemo & useCallback
他们都可以用来优化子组件的渲染问题,或者监听子组件状态变化来处理事件,这一点在以前是很难做到的,因为shouldComponentUpdate 里能监听到是否变化,但没法控制其他的外部方法,只能返回true和false,而componentDidUpdate只能在更新后执行,所以想在渲染之前做些事情就不好搞了。
useCallback目前还不能用
import React, { useState, useMemo } from 'react';const Child = ({ age, name, children }) => {//在不用useMemo做处理的时候,只要父组件状态改变了,子组件都会渲染一次,用了useMemo可以监听某个状态name,当name变化时候执行useMemo里第一个函数console.log(age, name, children, '11111111');function namechange() {console.log(age, name, children, '22222222');return name + 'change';}{/** react 官网虽说useCallback与useMemo的功能差不多,但不知道版本问题还怎么回是,这个方法目前还不能用const memoizedCallback = useCallback(() => {console.log('useCallback')},[name],);console.log(memoizedCallback,'memoizedCallback')*/}//useMemo有两个参数,和useEffect一样,第一个参数是函数,第二个参数是个数组,用来监听某个状态不变化const changedname = useMemo(() => namechange(), [ name ]);return (<div style={{ border: '1px solid' }}><p>children:{children}</p><p>name:{name}</p><p>changed:{changedname}</p><p>age:{age}</p></div>);
};const UseMemo = () => {//useState 设置名字和年龄,并用2两个按钮改变他们,传给Child组件const [ name, setname ] = useState('baby张'); const [ age, setage ] = useState(18);return (<div><buttononClick={() => {setname('baby张' + new Date().getTime()); }}>改名字</button><buttononClick={() => {setage('年龄' + new Date().getTime());}}>改年龄</button><p>UseMemo {name}:{age}</p><Child age={age} name={name}>{name}的children</Child></div>);
};export default UseMemo;
4.useRef
ref跟之前差不多,useRef创建–绑定–使用,三步走,详细看代码以及备注
import React, { useState, useRef } from 'react';const UseRef = () => {//这里useState绑定个input,关联一个状态nameconst [ name, setname ] = useState('baby张');const refvalue = useRef(null);// 先创建一个空的useReffunction addRef() {refvalue.current.value = name; //点击按钮时候给这个ref赋值// refvalue.current = name //这样写时,即使ref没有绑定在dom上,值依然会存在创建的ref上,并且可以使用它console.log(refvalue.current.value);}return (<div><inputdefaultValue={name}onChange={(e) => {setname(e.target.value);}}/><button onClick={addRef}>给下面插入名字</button><p>给我个UseRef名字:</p><input ref={refvalue} /></div>);
};export default UseRef;
5.useContext
之前使用过context的小伙伴一看就懂,useContext的话跟之前的context基本用法差不多,代码内有详细注释说明,创建,传值,使用
import React, { useState, useContext, createContext } from 'react';const ContextName = createContext();
//这里为了方便写博客,爷爷孙子组件都写在一个文件里,正常需要在爷爷组件和孙子组件挨个引入创建的Contextconst UseContext = () => {//这里useState创建一个状态,并按钮控制变化const [ name, setname ] = useState('baby张');return (<div><h3>UseContext 爷爷</h3><buttononClick={() => {setname('baby张' + new Date().getTime());}}>改变名字</button>{/**这里跟context用法一样,需要provider向子组件传递value值,value不一定是一个参数 */}}<ContextName.Provider value={{ name: name, age: 18 }}>{/**需要用到变量的子组件一定要写在provider中间,才能实现共享 */}<Child /></ContextName.Provider></div>);
};const Child = () => {//创建一个儿子组件,里面引入孙子组件return (<div style={{ border: '1px solid' }}>Child 儿子<ChildChild /></div>);
};const ChildChild = () => {//创建孙子组件,接受爷爷组件的状态,用useContext,获取到爷爷组件创建的ContextName的value值let childname = useContext(ContextName);return (<div style={{ border: '1px solid' }}>ChildChild 孙子<p>{childname.name}:{childname.age}</p></div>);
};export default UseContext;
6.useReducer
这里的usereducer会返回state和dispatch,通过context传递到子组件,然后直接调用state或者触发reducer,我们常用useReducer 与useContext createContext一起用,模拟reudx的传值和重新赋值操作。
import React, { useState, useReducer, useContext, createContext } from 'react';//初始化stroe的类型、初始化值、创建reducer
const ADD_COUNTER = 'ADD_COUNTER';
const initReducer = {count: 0
};
//正常的reducer编写
function reducer(state, action) {switch (action.type) {case ADD_COUNTER:return { ...state, count: state.count + 1 };default:return state;}
}const CountContext = createContext();
//上面这一段,初始化state和reducer创建context,可以单独写一个文件,这里为了方便理解,放一个文件里写了const UseReducer = () => {const [ name, setname ] = useState('baby张');//父组件里使用useReducer,第一个参数是reducer函数,第二个参数是state,返回的是state和dispashconst [ state, dispatch ] = useReducer(reducer, initReducer);return (<div>UseReducer{/* 在这里通过context,讲reducer和state传递给子组件*/}<CountContext.Provider value={{ state, dispatch, name, setname }}><Child /></CountContext.Provider></div>);
};const Child = () => {//跟正常的接受context一样,接受父组件的值,通过事件等方式触发reducer,实现redux效果const { state, dispatch, name, setname } = useContext(CountContext);function handleclick(count) {dispatch({ type: ADD_COUNTER, count: 17 });setname(count % 2 == 0 ? 'babybrother' : 'baby张');}return (<div><p>{name}今年{state.count}岁</p><button onClick={() => handleclick(state.count)}>长大了</button></div>);
};export default UseReducer;
相关文章:
React hook 10种常见 Hook
React Hook是什么? React官网是这么介绍的: Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。 完全可选的 你无需重写任何已有代码就可以在一些组件中尝试 Hook。但是如果你不想,你不…...

图文详解PhPStudy安装教程
版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 官方下载 请在PhPStudy官方网站下载安装文件,官方链接如下:https://m.xp.cn/linux.html;图示如下: 请下载PhPStudy安装文件…...

stable diffusion实践操作-hypernetworks
系列文章目录 本文专门开一节写hypernetworks的内容,在看之前,可以同步关注: stable diffusion实践操作 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、h…...

Win10搭建VisualSvn Server
Win10搭建VisualSvn Server 目录 Win10搭建VisualSvn Server一、下载VisualSvn Server安装包二、安装VisualSvn Server三、配置和使用VisualSVN Server四、添加用户及权限设定方法五、创建目录及配置权限 1、服务端:有集成了Subversion和Apache、安装使用非常简单且…...
Golang网络编程
Golang网络编程 网络编程简介网络编程协议网络分层模型TCP/IP协议什么是DNS套接字(Socket)客户端服务器模型TCP/UDP的区别HTTP协议会话sessionCookiehttpsHTTP请求格式HTTP响应格式http头信息http请求头信息http响应头信息HTTP状态码http内容类型和内容…...

详解vue3中ref和reactive用法和区别
vue3中ref和reactive区别 1、前言2、基本用法2.1 ref2.2 reactive 3、ref和reactive定义数组对比3.1 ref定义数组3.1 reactive定义数组 4、ref 和reactive的区别 1、前言 ref和reactive是Vue3中用来实现数据响应式的API,一般情况下,ref定义基本数据类型…...

QML与C++的交互操作
QML旨在通过C 代码轻松扩展。Qt QML模块中的类使QML对象能够从C 加载和操作,QML引擎与Qt元对象系统集成的本质使得C 功能可以直接从QML调用。这允许开发混合应用程序,这些应用程序是通过混合使用QML,JavaScript和C 代码实现的。除了从QML访问…...

Java_理解方法调用
理解方法调用 首先什么是隐式参数 --->隐式参数是调用该方法的对象本身。 接下来方法的名称和参数列表被称为方法的签名(signature)。在Java中,方法的签名由方法的名称和参数列表组成,用于唯一标识一个方法。返回类型不是签名的…...

Mysql 性能分析(慢日志、profiling、explain)、读写分离(主从架构)、分库分表(垂直分库、垂直分表、水平分表)
查看系统性能参数 一条sql查询语句在执行前,需要确定查询执行计划,如果存在多种执行计划的话,mysql会计算每个执行计划所需要的成本,从中选择 成本最小的一个作为最终执行的执行计划 想要查看某条sql语句的查询成本,可…...

获取Linux内核源码
在嵌入式平台上做Linux开发的时候,我们用的kernel都是芯片厂家移植到自家平台上的,但是最初的原生Linux内核的源码是从哪里来的呢?下面我们介绍一下怎么获取原生的Linux源码。 从Linux社区获取内核kernel源码 Linux社区的官方网站是 https:…...

【Maven教程】(四)坐标与依赖:坐标概念,依赖配置、范围、传递性和最佳实践 ~
Maven 坐标与依赖 1️⃣ 什么是Maven 坐标2️⃣ 坐标详解3️⃣ 依赖的配置4️⃣ 依赖范围5️⃣ 传递性依赖6️⃣ 依赖调解7️⃣ 可选依赖8️⃣ 最佳实践8.1 排除依赖8.2 归类依赖8.3 优化依赖 🌾 总结 正如前面文章所述,Maven 的一大功能是管理项目依赖…...

Java“牵手”京东店铺所有商品API接口数据,通过店铺ID获取整店商品详情数据,京东店铺所有商品API申请指南
京东平台店铺所有商品数据接口是开放平台提供的一种API接口,通过调用API接口,开发者可以获取京东整店的商品的标题、价格、库存、月销量、总销量、库存、详情描述、图片、价格信息等详细信息 。 获取店铺所有商品接口API是一种用于获取电商平台上商品详…...

TuyaOS开发学习笔记(1)——NB-IoT开发搭建环境、编译烧写(MT2625)
一、搭建环境 1.1 官方资料 TuyaOS 1.2 安装VMware 官网下载:https://customerconnect.vmware.com/en/downloads/info/slug/desktop_end_user_computing/vmware_workstation_pro/16_0 百度网盘:https://pan.baidu.com/s/1oN7H81GV0g6cD9zsydg6vg 提取…...
Css 将div设置透明度,并向上移50px,盖住上面的元素一部分
可以使用CSS中的opacity和position属性来实现。 首先,将div的opacity属性设置为小于1的值,比如0.5,这样就可以设置透明度了。其次,将div的position设置为relative,然后再将它向上移动50px,即可盖住上面的元…...

HTTPS安全通信和SSL Pinning
随着互联网的迅速发展,网络通信安全问题日益凸显。在这一背景下,HTTPS作为一种加密通信协议得到了广泛应用,以保障用户的数据隐私和信息安全。本文将介绍HTTPS的基本原理、发展历程,以及与之相关的中间人攻击和防护方法。 1. HTT…...

PHP自己的框架PDO数据表前缀、alias、model、table、join方法实现(完善篇九--结束)
一、实现功能,数据表前缀、alias、model、table、join方法实现 二、表前缀实现 1、config.php增加表前缀 DB_PEX>fa_,//数据库前缀 2、增加表前缀方法function.php function model($table){$modelnew ModelBase($table,config("DB_PEX"));return $m…...

华为OD:敏感字段加密
题目描述: 给定一个由多个命令字组成的命令字符串: 1、字符串长度小于等于127字节,只包含大小写字母,数字,下划线和偶数个双引号; 2、命令字之间以一个或多个下划线_进行分割; 3、可以通过两个双引号”"来标识包含下划线…...

IDEA新建SpringBoot项目时启动编译报错:Error:java: 无效的源发行版: 17
文章目录 原因检查解决步骤修改jdk修改SpringBoot版本 原因 出现这种错误的原因可能是: 本机默认使用(编译)的jdk与该项目所使用的jdk版本不同。 jdk版本不适用于这个Idea,很典型的一个例子就是使用的Idea是2020的,而…...

【云原生进阶之PaaS中间件】第一章Redis-2.3.3集群模式
1 集群模式 Redis集群是一个提供在多个Redis节点之间共享数据的程序集。它并不像Redis主从复制模式那样只提供一个master节点提供写服务,而是会提供多个master节点提供写服务,每个master节点中存储的数据都不一样,这些数据通过数据分片的方式被自动分割到不同的master节点上…...

游戏发行商能够提供什么服务?
游戏发行商可以为游戏开发者提供广泛的服务,以帮助他们将游戏成功地引入市场并取得更好的业绩。以下是游戏发行商可能提供的一些服务: 市场营销和宣传:发行商通常具有丰富的市场营销经验,可以制定并执行有效的宣传和营销策略。他们…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...