概念+示例+横向对比+难点解析征服八大react hooks

news/2024/4/26 23:01:03/文章来源:https://blog.csdn.net/qq_33925054/article/details/129238450

8大hooks概念、使用场景

前言

对不同阶段的react开发者会有不同的效果,最终目的是能够对8大react hooks,完全理解,游刃有余。对比useState和useReducer,什么时候使用useMemo和useCallback,useEffect的参数… …

useState

概念

定义类组件的状态

相关问题

为什么usestate是数组

如果 useState 返回的是数组,那么使用者可以对数组中的元素命名,代码看起来也比较干净 如果 useState 返回的是对象,在解构对象的时候必须要和 useState 内部实现返回的对象同名,想要使用多次的话,必须得设置别名才能使用返回值

useEffect

概念

  • 副作用hooks
  • 给没有生命周期的组件,添加结束渲染的信号
  • 执行时机:在渲染结束之后执行
  • 不管什么场景下,useEffect都会在初次渲染期间执行

示例

import React,{ useEffect, useState } from 'react'function StateFunction () {const [num, setNum] = useState(0)useEffect( () => {console.log('函数式组件结束渲染')const updateMouse = (e) => {console.log('打印当前位置')setPositions({ x:e.clientX, y:e.clientY })}document.addEventListener('click',updateMouse) //  添加绑定方法事件(要修改依赖,绑定到依赖上)return () => {//  在每次执行useEffect之前都会执行上一次return中内容document.removeEventListener('click',updateMouse)//  移除绑定方法事件(要修改依赖,绑定到依赖上)console.log('1111销毁')}})
}

1.第一个参数,接收一个函数作为参数
2.第二个参数,接收【依赖列表】,只有依赖更新时,才会执行函数
3.返回一个函数,先执行返回函数,再执行参数函数

useLayoutEffect

概念

一般将useLayoutEffect称为有DOM操作的副作用hooks。作用是在DOM更新完成之后执行某个操作。执行时机:在DOM更新之后执行。
与eusEffect不同点:执行示例代码会发现useLayoutEffect永远比useEffect先执行,这是因为DOM更新之后,渲染才结束或者渲染还会结束。

useMemo

概念

传递一个创建函数和依赖项,创建函数会需要返回一个值,只有在依赖项发生改变的时候,才会重新调用此函数,返回一个新的值

useCallback

概念

父组件的传入函数不更新,就不会触发子组件的函数重新执行

示例

function Parent () {const [num, setNum] = useState(1)const [age, setAge] = useState(18)const getDoubleNum = useCallback( () => {console.log(`获取双倍Num${num}`)return 2 * num},[num] )return (<div onClick={ () => {setNum( num => num+1 )} }>这是一个函数式组件————num:{  getDoubleNum() }<br></br>age的值为————age:{ age }<br></br>set.size:{set.size}<Child callback={ getDoubleNum() }></Child></div>)
}function Child(props) {useEffect( () => {console.log('callback更新了') //这里代表的是需要跟随传入内容的改变而同步进行的操作},[props.callback])return (<div>子组件的getDoubleNum{props.callback}</div>)
}

总结

在子组件不需要父组件的值和函数的情况下,只需要使用memo函数包裹子组件即可
如果有函数传递给子组件,使用useCallback
缓存一个组件内的复杂计算逻辑需要返回值时,使用useMemo

useRef

概念

返回一个子元素索引,此索引在整个生命周期中保持不变。
作用也就是:长久保存数据。
注意事项,保存的对象发生改变,不通知。属性变更不会重新渲染

示例

const [num, setNum] = useState(0)const ref = useRef()
useEffect( () => {ref.current = setInterval( () => {setNum( num => num+1 )},400 )// ref.current = '111'
},[] )useEffect( () => {if(num > 10){console.log('大于10了,清除定时器')console.log('ref.current',ref.current)clearTimeout(ref.current)}
},[num] )return (<div>这是一个函数式组件————num:{  num }</div>
)

useContext

概念

useContext是让子组件之间共享父组件传入的状态的,特别是推荐应用程序需要在比两层更深的组件之间共享状态时使用,或者父组件有传入一个值到多个不同的子组件中。

示例

一个值到多个的使用前
function StateFunction () {const [num, setNum] = useState(1)return (<div><button onClick={ ()=> setNum(num => num+1) }>增加num的值+1</button><br></br>这是一个函数式组件——num:{  num }<Item1 num={num}></Item1><Item2 num={num}></Item2>//	......</div>)
}function Item1 (props) {return (<div>子组件1 num:{ props.num }</div>)
}function Item2 (props) {return (<div>子组件2 num:{ props.num }</div>)
}
一个值到多个使用后
const Context = createContext(null)function StateFunction () {const [num, setNum] = useState(1)return (<div><button onClick={ ()=> setNum(num => num+1) }>增加num的值+1</button><br></br>这是一个函数式组件——num:{  num }<Context.Provider value={num}><Item3></Item3><Item4></Item4></Context.Provider></div>)
}function Item3 () {const num = useContext(Context)return (<div>子组件3: { num }</div>)
}function Item4 () {const num = useContext(Context)return (<div>子组件4: { num+2 }</div>)
}
一传多优化总结

使用useContext优化后,代码如下,这样我们只需要在子组件中使用useContext(Context句柄)来获取数据即可,添加同类子组件时不需要再关注父组件中子组件定义时的props传入值,使用方法如下

需要引入useContetx,createContext两个内容
通过createContext创建一个context句柄
Context.Provider来确定数据共享范围
通过value来分发内容
在子组件中,通过useContext(Context句柄)来获取数据
注意事项,上层数据发生改变,肯定会触发重新渲染(点击button按钮触发父组件更新传入的num值能看到子组件重新渲染)

两层以上子组件传递
const ContextA = createContext(null);const Parent = () => {const [stateA, dispatchA] = useReducer(reducerA, initialStateA);const valueA = useMemo(() => [stateA, dispatchA], [stateA]);return (<ContextA.Provider value={valueA}><Child1 /></ContextA.Provider>);
};const Child1 = () => (<GrandChild1 />
);const GrandChild1 = () => (<GrandGrandChild1 />
);const GrandGrandChild1 = () => {const [stateA, dispatchA] = useContext(ContextA);return (...);
};
多个值的Context

🙅👇
在这里插入图片描述
🙆下面
推荐使用这个开源库【 react-hooks-global-state】

import { createGlobalState } from 'react-hooks-global-state';const initialState = { a: ...,b: ...,c: ...,
};
const { GlobalStateProvider, useGlobalState } = createGlobalState(initialState);const App = () => (<GlobalStateProvider>...</GlobalStateProvider>
);const Component1 = () => {const [valueA, updateA] = useGlobalState('a');return (...);
};
Q: 如何跨文件使用Context这个变量

A: 把这个Ctx 直接暴露出去 即 export const Ctx = createContext();
伪代码:

// ParentComponent
export let Context = createContext(null)
const ParentComponent = ()=>{
let [num, setNum] = useState(1)
return (<div><Context.Provider value={{num,setNum}}<grandChild show={True}></Context.Provider ><button onClick=()=>setNum(num + 1)>+1</button></div>)	
}
export default ParentComponent;// grandChildComponentimport {Context} form './ParentComponent'
const grandChildComponent = ()=>{return (<Context.Consumer>{value=>(<div><span>{value.num}</span><button onClick={()=>value.setNum(value.num+1)}>+1</button></div>)}</Context.Consumer>)
}
export default grandChildComponent;

具体写法可以参考隔壁

useReducer

概念

useReducer通过向下传递分派(而不是回调)让子组件之间共享父组件传入的状态。涉及多个子值的复杂状态逻辑或下一个状态依赖于前一个状态时,可以优化触发深度更新的组件的性能。
使用useReducerwhich 返回一个dispatch在重新渲染之间不会改变的方法,并且您可以在 reducer 中拥有操作逻辑。

示例

const store = {age:18,num:1
}	//	数据仓库const reducer = (state, action) => {switch(action.type){case 'add':return {...state,num: action.num+1}default:return {...state}}
} //	管理者function StateFunction () {const [state,dispacth] = useReducer(reducer,store)  //	①return (<div><button onClick={ () => {dispacth({type: 'add',num: state.num})} }>增加num的值+1</button><br></br>这是一个函数式组件——num:{  state.num }</div>)
}

即是:
创建数据仓库store(状态)和管理者reducer(动作),定义一个数组获取状态和改变状态的动作,触发动作的时候需要传入type类型判断要触发reducer哪个动作,然后进行数据的修改。需要注意的地方是,在reducer中return的对象中,需要将state解构,否则状态就剩下一个num值了

与useState的区别

在这里插入图片描述

引用

理解和引用的传送门👇

  • 掌握及对比常用的8个Hooks(优化及使用场景)
  • Four patterns for global state with React hooks: Context or Redux
  • React Hooks: useState 和 useReducer 有什么区别?
  • Hooks API Reference
  • useState vs useReducer
  • usestate vs usereducer hooks

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

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

相关文章

文献阅读笔记 # 面向大规模多版本软件系统的代码克隆检测加速技术

面向大规模多版本软件系统的代码克隆检测加速技术&#xff0c;方维康 吴毅坚 赵文耘&#xff0c;《计算机应用与软件》复旦大学软件学院、复旦大学上海市数据科学重点实验室2022 April 面向大规模多版本软件系统的代码克隆检测加速技术 摘要 很多代码克隆检测方法主要针对软…

【博学谷学习记录】超强总结,用心分享丨人工智能 多场景实战 常用英文缩写概念总结

目录PV(Page View)UV(Unique Visitor)CPM(Cost Per Mille)CPC(Cost Per Click)CPA(Cost Per Action)CPI(Cost Per Install)ACU(Average concurrent users)PCU(Peak concurrent users)ARPU(Average Revenue Per User)ARPPU(Average Revenue Per Paying User)LTV(Life Time Value…

Linux命令之lz4命令

一、lz4命令简介 LZ4是一种压缩格式&#xff0c;特点是压缩/解压缩速度超快(压缩率不如gzip)&#xff0c;如果你特别在意压缩速度&#xff0c;或者当前环境的CPU资源紧缺&#xff0c;可以考虑这种格式。lz4是一种非常快速的无损压缩算法&#xff0c;基于字节对齐LZ77系列压缩方…

西电计算机通信与网络(计网)简答题计算题核心考点汇总(期末真题+核心考点)

文章目录前言一、简答计算题真题概览二、网桥&#xff0c;交换机和路由器三、ARQ协议四、曼彻斯特编码和差分曼彻斯特编码五、CRC六、ARP协议七、LAN相关协议计算前言 主要针对西安电子科技大学《计算机通信与网络》的核心考点进行汇总&#xff0c;包含总共26章的核心简答。 【…

【Linux】Linux根文件系统扩容

场景&#xff1a;根文件系统需要至少100GB的剩余空间&#xff0c;但是目前就剩余91GB。因此&#xff0c;我们需要对根文件系统进行扩容。# df -h 文件系统 容量 已用 可用 已用% 挂载点 devtmpfs 3.9G 0 3.9G 0% /dev tmpfs …

密码暴力破解

密码的暴力破解准备工具功能简介Burp Intruder工作原理Intruder应用场景爆破实操准备工具 首先准备好BurpSuite和Dvwa作为测试工具和实验对象。 功能简介 Burp Intruder工作原理 Intruder在原始请求数据的基础上&#xff0c;通过修改各种请求参数&#xff0c;以获取不同的请…

flutter 微信聊天输入框

高仿微信聊天输入框&#xff0c;效果图如下&#xff08;目前都是静态展示&#xff0c;服务还没开始开发&#xff09;&#xff1a; 大家如果观察仔细的话 应该会发现&#xff0c;他输入框下面的高度 刚好就是 软键盘的高度&#xff1b;所以在这里就需要监听软键盘的高度。还要配…

Hbase资源隔离操作指南

1.检查集群的环境配置 1.1 HBase版本号确认> 5.11.0 引入rsgroup的Patch&#xff1a; [HBASE-6721] RegionServer Group based Assignment - ASF JIRA RegionServer Group based Assignment 社区支持版本&#xff1a;2.0.0 引入rsgroup的CDH版本 5.11.0 https://www.…

购买运动耳机应该考虑什么问题、运动达人必备的爆款运动耳机

喜欢运动的小伙伴都知道&#xff0c;运动和音乐是最配的&#xff0c;在运动中伴随着节奏感的音乐能够让自己更兴奋&#xff0c;锻炼的更加起劲儿。在运动耳机方面我也一直都有所研究&#xff0c;购买运动耳机最重要的就是要满足我们运动时候听音乐的需求&#xff0c;从佩戴舒适…

《C++ Primer Plus》(第6版)第5章编程练习

《C Primer Plus》&#xff08;第6版&#xff09;第5章编程练习《C Primer Plus》&#xff08;第6版&#xff09;第5章编程练习1. 计算闭区间内的整数和2. 重新编写程序清单5.43. 累加4. 投资价值5. 销售情况6. 销售情况27. 汽车8. 销售情况29. 销售情况210. 销售情况2《C Prim…

【技术美术图形部分】简述主流及新的抗锯齿技术

电脑的世界里没有曲线&#xff0c;都是三角面组成一个个模型的&#xff0c;因此一定会出现走样&#xff08;锯齿&#xff09;的情况&#xff0c;只是严重与否的问题&#xff0c;而AA也是实时渲染最难解决的问题之一。 Sampling&Artifacts Lecture 06 Rasterization 2 (An…

MAML算法详解(元学习)

文章目录回顾元学习MAML算法MAML和预训练模型的区别数学推导MAML实施细节总结回顾元学习 元学习的基本知识参考这篇博客元学习和机器学习的对比 MAML算法 学习初始化参数&#xff0c;所有任务的初始化的参数都是一样的 MAML和预训练模型的区别 MAML使用的是ϕ\phiϕ…

阶段十:总结专题(第六章:缓存篇)

阶段十&#xff1a;总结专题&#xff08;第六章&#xff1a;缓存篇&#xff09;Day-第六章&#xff1a;缓存篇1. Redis 数据类型**String****List****Hash****Sorted Set**2. keys 命令问题3. 过期 key 的删除策略4. Redis 持久化**AOF 持久化****AOF 重写****RDB 持久化****混…

Python 中 openpyxl 模块封装,读写 Excel 文件中自动化测试用例数据

只有测试数据和错误提示信息不同&#xff0c;其他代码都是一样的&#xff0c;不这样不易修改数据和维护&#xff0c;会有两点痛点 1.代码冗余极其严重, 程序可读性不佳 2.程序拓展性很差 往往我们在自动化测试汇总&#xff0c;会将数据放在 Excel 文件、CSV文件、数据库 Py…

Python-scatter散点图及颜色大全

# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as pltplt.rcParams[font.sans-serif][SimHei] plt.rcParams[axes.unicode_minus] False #matplotlib画图中中文显示会有问题&#xff0c;需要这两行设置默认字体plt.xlabel(X) plt.ylabel(Y) plt.xlim…

【IP技术】ipv4和ipv6是什么?

IPv4和IPv6是两种互联网协议&#xff0c;用于在互联网上标识和寻址设备。IPv4&#xff08;Internet Protocol version 4&#xff09;是互联网协议的第四个版本&#xff0c;是当前广泛使用的互联网协议。IPv4地址由32位二进制数构成&#xff0c;通常表示为4个十进制数&#xff0…

大数据技术之Hive(四)分区表和分桶表、文件格式和压缩

一、分区表和分桶表1.1 分区表partitionhive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录&#xff0c;每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择式选择查询所需要的分区&#xff0c;这样的查询效率辉提高很多。1.1.1 分区表基本语…

2023年蜂巢科技最新面试题

2023年蜂巢科技最新面试题 bio与nio的区别 bio同步阻塞io&#xff1a;在此种⽅式下&#xff0c;⽤户进程在发起⼀个IO操作以后&#xff0c;必须等待IO操作的完成&#xff0c;只有当真正完成了IO操作以后&#xff0c;⽤户进程才能运⾏。JAVA传统的IO模型属于此种⽅式&#xff0…

flink常用算子介绍

flink任务中【Transformation 数据转换】是对数据进行操作&#xff0c;有 Map、FlatMap、Filter、KeyBy 、Reduce 、Fold 、Aggregations、Window 、WindowAll 、Union 、Window join 、Split 、Select 、Project 等&#xff0c;通过对数据的操作&#xff0c;转换成想要的数据&…

HttpRunnerManager部署

基于HttpRunner的接口自动化测试平台: HttpRunner, djcelery and Django_. HttpRunner手册: http://cn.httprunner.org/git地址&#xff1a;httprunner/HttpRunnerManager: 基于 HttpRunner 的 Web 测试平台&#xff0c;已停止维护。 (github.com)部署机器&#xff1a;linux部署…