当前位置: 首页 > 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;可以制定并执行有效的宣传和营销策略。他们…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...