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节点上…...

游戏发行商能够提供什么服务?
游戏发行商可以为游戏开发者提供广泛的服务,以帮助他们将游戏成功地引入市场并取得更好的业绩。以下是游戏发行商可能提供的一些服务: 市场营销和宣传:发行商通常具有丰富的市场营销经验,可以制定并执行有效的宣传和营销策略。他们…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...