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

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 ()=>{ } } , [ ])第一个参数,是函数,默认第一次渲染和更新时都会触发,默认自带一个returnreturn一个函数表示可以再销毁之前可以处理些事情
第二个参数,数组【】,空的时候表示只执行一次,更新时不触发,里面的参数是什么,当参数变化时才会执行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是什么&#xff1f; React官网是这么介绍的&#xff1a; Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。 完全可选的 你无需重写任何已有代码就可以在一些组件中尝试 Hook。但是如果你不想&#xff0c;你不…...

图文详解PhPStudy安装教程

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

stable diffusion实践操作-hypernetworks

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

Win10搭建VisualSvn Server

Win10搭建VisualSvn Server 目录 Win10搭建VisualSvn Server一、下载VisualSvn Server安装包二、安装VisualSvn Server三、配置和使用VisualSVN Server四、添加用户及权限设定方法五、创建目录及配置权限 1、服务端&#xff1a;有集成了Subversion和Apache、安装使用非常简单且…...

Golang网络编程

Golang网络编程 网络编程简介网络编程协议网络分层模型TCP/IP协议什么是DNS套接字&#xff08;Socket&#xff09;客户端服务器模型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&#xff0c;一般情况下&#xff0c;ref定义基本数据类型…...

QML与C++的交互操作

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

Java_理解方法调用

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

Mysql 性能分析(慢日志、profiling、explain)、读写分离(主从架构)、分库分表(垂直分库、垂直分表、水平分表)

查看系统性能参数 一条sql查询语句在执行前&#xff0c;需要确定查询执行计划&#xff0c;如果存在多种执行计划的话&#xff0c;mysql会计算每个执行计划所需要的成本&#xff0c;从中选择 成本最小的一个作为最终执行的执行计划 想要查看某条sql语句的查询成本&#xff0c;可…...

获取Linux内核源码

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

【Maven教程】(四)坐标与依赖:坐标概念,依赖配置、范围、传递性和最佳实践 ~

Maven 坐标与依赖 1️⃣ 什么是Maven 坐标2️⃣ 坐标详解3️⃣ 依赖的配置4️⃣ 依赖范围5️⃣ 传递性依赖6️⃣ 依赖调解7️⃣ 可选依赖8️⃣ 最佳实践8.1 排除依赖8.2 归类依赖8.3 优化依赖 &#x1f33e; 总结 正如前面文章所述&#xff0c;Maven 的一大功能是管理项目依赖…...

Java“牵手”京东店铺所有商品API接口数据,通过店铺ID获取整店商品详情数据,京东店铺所有商品API申请指南

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

TuyaOS开发学习笔记(1)——NB-IoT开发搭建环境、编译烧写(MT2625)

一、搭建环境 1.1 官方资料 TuyaOS 1.2 安装VMware 官网下载&#xff1a;https://customerconnect.vmware.com/en/downloads/info/slug/desktop_end_user_computing/vmware_workstation_pro/16_0 百度网盘&#xff1a;https://pan.baidu.com/s/1oN7H81GV0g6cD9zsydg6vg 提取…...

Css 将div设置透明度,并向上移50px,盖住上面的元素一部分

可以使用CSS中的opacity和position属性来实现。 首先&#xff0c;将div的opacity属性设置为小于1的值&#xff0c;比如0.5&#xff0c;这样就可以设置透明度了。其次&#xff0c;将div的position设置为relative&#xff0c;然后再将它向上移动50px&#xff0c;即可盖住上面的元…...

HTTPS安全通信和SSL Pinning

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

PHP自己的框架PDO数据表前缀、alias、model、table、join方法实现(完善篇九--结束)

一、实现功能&#xff0c;数据表前缀、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:敏感字段加密

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

IDEA新建SpringBoot项目时启动编译报错:Error:java: 无效的源发行版: 17

文章目录 原因检查解决步骤修改jdk修改SpringBoot版本 原因 出现这种错误的原因可能是&#xff1a; 本机默认使用&#xff08;编译&#xff09;的jdk与该项目所使用的jdk版本不同。 jdk版本不适用于这个Idea&#xff0c;很典型的一个例子就是使用的Idea是2020的&#xff0c;而…...

【云原生进阶之PaaS中间件】第一章Redis-2.3.3集群模式

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

游戏发行商能够提供什么服务?

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

C++_核心编程_多态案例二-制作饮品

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

高频面试之3Zookeeper

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

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 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元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...