【react】Hooks原理和实战

news2024/11/17 23:39:39

前言

在最初学习react的时候,我们大部分会选择去扒一扒React的官方文档,看看他是什么,怎么使用的。而我却很好奇在文档里学习的第一个完整的组件是 类(Class)组件,但是在实际工作中我们看到项目中所声明的组件都是以函数的形式所展示的。于是一个小小的疑问引起了我对新知识的探索。原来随着项目的发展,组件会被越来越多复杂的状态逻辑和副作用充斥,对于例如事件的监听移除这种成对出现的逻辑被拆分到不同的方法中,而又有很多完全不相关的代码却组合在了一起,就会产出许多的bug。甚至在项目打包Class不能很好的被压缩,并会使热重载出现不稳定的情况等等…Facebook的工程师们想到一个很好的替代方案引入一个API,让函数组件拥有Class组件一样的状态管理的能力,和完整的生命周期函数。他就是Hook。但是我们依旧可以继续使用Class组件。

Hook是什么

Hook是React16.8新增的特性,目的就是为了让开发者在不编写Class的情况下使用state,实现组件的生命周期,Ref以及其他的React特性。

举个例子:在这里插入图片描述在这里插入图片描述

hooks原理

推荐一个博主编写的极简实现useState的博客:React技术揭秘 里边讲述了react useState底层实现的原理。然后配合 GitHub - acdlite/react: A declarative, efficient, and flexible JavaScript library for building user interfaces. React源码尝试着理解Hook理念。

hooks的使用

  1. 使用StateHook

例如一般我们定义一个state变量

const [count , setCount] = useState(initValue);

initValue:就是设定初始的值

setCount的使用有两种情况

setCount( newValue ); //参数为非函数值时,直接指定新的状态值

setCount( oldValue =>{ … return newValue} ) //参数为函数时,接收原本的状态值,通过函数返回新的状态值

  1. 使用ReducerHook

一个升级版的useState,在某些场景下useRucer会比useSate更适用,例如state逻辑比较复杂且包含多个子值,或者下一个state依赖之前的state等。 原理类似redux,需要reducer 、action、dispather在这里插入图片描述initValue:就是设定初始的值

  1. 使用EffectHook

可以把useEffect 看做如下三个函数的组合


  componentDidMount( );

  componentDidUpdate( );

  componentWillUnmount( );

  useEffect( ( )=>{ }) ;       //监听所有useState变量的变化

                useEffect( ( )=>{

   return ( ) => {  //相当于componentWillUnmount  }

                 }) ;

                useEffect( ()=>{} , [ ] ) ;       //不监听任何变量         且函数只会在第一次 render( )  后执行    

                useEffect( ( )=>{ } , [name,list])//监听name list变量的变化
  1. 使用RefHook
  const inputEL = useRef( ); 声明一个标记容器

  <input type="text" ref={ inputEL } />

  inputEL.current.focus( );

  inputEL.current.blur( );
  1. 使用CallbackHook
    使用useCallback对函数进行缓存,组件再次更新时(函数组件重新render)时,会根据传入的依赖是否变化决定选用缓存函数还是新函数,比较的方式是浅比较 object.is( ).

在这里插入图片描述

我们用useCallback把函数包起来之后,在父组件中只有当Text, isKey变化的时候,才会创建新的handleIneerHTML实例,子组件才会跟着reRender

  1. 使用MemoHook
    要注意区分 useMemo 和 React.memo( ) 的区别哦

如果useMemo(fn, arr)第二个参数匹配,并且其值发生改变,才会多次执行执行,否则只执行一次,如果为空数组[],fn只执行一次

useMemo和useCallback都是reactHook提供的两个API,用于缓存数据,优化性能;两者接收的参数都是一样的,第一个参数表示一个回调函数,第二个表示依赖的数据。

共同的作用:在依赖数据发生变化的时候,才会调用传进去的回调函数去重新计算结果,起到一个缓存的作用

两者的区别:useMemo 缓存的结果是回调函数中return回来的值,主要用于缓存计算结果的值,应用场景如需要计算的状态

useCallback 缓存的结果是函数,主要用于缓存函数,应用场景如需要缓存的函数,因为函数式组件每次任何一个state发生变化,会触发整个组件更新,一些函数是没有必要更新的,此时就应该缓存起来,提高性能,减少对资源的浪费;另外还需要注意的是,useCallback应该和React.memo配套使用,缺了一个都可能导致性能不升反而下降。

  1. 使用ContextHook
    我们想实现一个按钮改变其他组件文字颜色的需求在这里插入图片描述在这里插入图片描述使用context进行数据通信,需要让context组件对所有需要用到共享数据的组件进行包裹,这里的props.childRender( ) 用到的是一个类似插槽的语法,这个由外层父组件传进来的是一个jsx语法,里面是需要共享数据的子组件在这里插入图片描述一下就是子组件通过useContext 拿到的共享数据

TextComponent组件

在这里插入图片描述
Buttons组件在这里插入图片描述

  1. 自定义Hook
    一个程序会有多个组件,在其中可能会调用同一个功能,我们为了避免每次需要调用这个功能时就在自己的组件里重复写同一个逻辑,所以我们需要将这个逻辑抽离出来,作为一个公共的Hook 来调用,例如项目中用到的监听窗口尺寸改变的自定义Hook在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

无涯教程-JavaScript - ERFC.PRECISE函数

描述 ERFC.PRECISE函数返回x和无穷大之间集成的互补ERF函数。 互补误差函数等于1-ERF(即1-误差函数),由等式给出- $$Erfc(x) \frac {2} {\sqrt {\pi}} \int_ {x} ^ {\infty} e ^ {-t ^ 2} dt $$ 语法 ERFC.PRECISE(x)争论 Argument描述Required/OptionalxThe lower bound…

K8s 多集群实践思考和探索

作者&#xff1a;vivo 互联网容器团队 - Zhang Rong 本文主要讲述了一些对于K8s多集群管理的思考&#xff0c;包括为什么需要多集群、多集群的优势以及现有的一些基于Kubernetes衍生出的多集群管理架构实践。 一、为什么需要多集群 随着K8s和云原生技术的快速发展&#xff0c…

如何优雅的实现一个Mybatis插件

定位&#xff1a;此篇尝试用另一种角度描述如何完成一个mybatis插件&#xff0c;全程可以按段落跳跃阅读&#xff0c;有任何不适欢迎指出Thanks♪(&#xff65;ω&#xff65;)&#xff89; 为什么这么设计 如果我想实现一个orm增强插件&#xff0c;首先就应该避免硬编码&…

C#写一个UDP程序判断延迟并运行在Centos上

服务端 using System.Net.Sockets; using System.Net;int serverPort 50001; Socket server; EndPoint client new IPEndPoint(IPAddress.Any, 0);//用来保存发送方的ip和端口号CreateSocket();void CreateSocket() {server new Socket(AddressFamily.InterNetwork, SocketT…

低代码是程序员“玩”出来的

一、前言 所谓“低代码”&#xff0c;最开始的雏形是程序员写一些重复的东西写腻了&#xff0c;产品今天想加个请假表&#xff0c;明天加个物资申请表&#xff0c;后天又想统计一下记录等等要求。对程序员来说开发这些就是一个个没意思的重复开发工作&#xff0c;所以就想着搞个…

LVGL Animations(动画)的简单使用

一、前言 哈喽&#xff0c;大家好。在进行界面设计的时候&#xff0c;动画的使用是必不可少的&#xff0c;今天这篇文章就跟大家分享一下 LVGL Animations&#xff08;动画&#xff09;的简单使用。笔者将在模拟器上运行演示&#xff0c;LVGL 版本号为 8.3.0。 二、Animation…

【HTML专栏3】!DOCTYPE、lang、字符集的作用

本文属于HTML/CSS专栏文章&#xff0c;适合WEB前端开发入门学习&#xff0c;详细介绍HTML/CSS如果使用&#xff0c;如果对你有所帮助请一键三连支持&#xff0c;对博主系列文章感兴趣点击下方专栏了解详细。 博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;HTML/CS…

当AI遇到IoT:开启智能生活的无限可能

文章目录 1. AI和IoT的融合1.1 什么是人工智能&#xff08;AI&#xff09;&#xff1f;1.2 什么是物联网&#xff08;IoT&#xff09;&#xff1f;1.3 AI和IoT的融合 2. 智能家居2.1 智能家居安全2.2 智能家居自动化 3. 医疗保健3.1 远程监护3.2 个性化医疗 4. 智能交通4.1 交通…

Json“牵手”易贝商品详情数据方法,易贝商品详情API接口,易贝API申请指南

易贝是一个可让全球民众在网上买卖物品的线上拍卖及购物网站&#xff0c;易贝&#xff08;EBAY&#xff09;于1995年9月4日由Pierre Omidyar以Auctionweb的名称创立于加利福尼亚州圣荷塞。人们可以在易贝上通过网络出售商品。2014年2月20日&#xff0c;易贝宣布收购3D虚拟试衣公…

Ros noetic 机器人坐标记录运动路径和发布 实战教程(C)

前言: 承接上一篇博文本文将编写并记录上文中详细的工程项目,用于保存小车的运动路径,生成对应的csv,和加载所保存的路径到实际的Rviz中,本文将开源完整的工程项目,工程结构如下: 工程原码位于文章末尾: 路径存储: waypoint_saver 用于存储 waypoint 的节点 waypo…

控制三盏灯

驱动代码 #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/io.h> #include "head.h"unsigned int major;//保存主设备号 char kbuf[128] {0}; unsigned int …

C# Emgu.CV+Tesseract实现识别图像验证码

效果图&#xff0c;简单的还行&#xff0c;复杂的。。。拉跨 懒得写讲解了&#xff0c;全部源码直接上吧 /// <summary>/// 验证码识别/// </summary>public partial class FrmCodeIdentify : FrmBase{private string _filePath;// 原图像Image<Bgr, byte> …

基于Python开发的DIY字符画程序(源码+可执行程序exe文件+程序配置说明书+程序使用说明书)

一、项目简介 本项目是一套基于Python开发的DIY字符画程序&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&…

Kafka3.0.0版本——消费者(消费者组初始化流程图解)

一、消费者组初始化流程图解 每个consumer都发送JoinGroup请求&#xff0c;如下图所示&#xff1a; 选出一个consumer作为leader&#xff0c;如下图所示&#xff1a; 把要消费的topic情况发送给leader 消费者&#xff0c;如下图所示&#xff1a; leader会负责制定消费方案…

MFC:自绘CListBox,GetText返回一个乱码

问题描述 自绘CListBox&#xff0c;GetText返回一个乱码&#xff0c;并且还会伴随以下断言 解决方案 ListBox Control 属性【Has Strings】改为True即可

【线程池处理任务】Runnable任务和Callable任务

线程池处理任务 ExecutorService的常用方法 方法名称说明void execute(Runnable command)执行 Runnable 任务Future< T > submit(Callable< T > task)执行 Callable 任务&#xff0c;返回未来任务对象&#xff0c;用于获取线程返回的结果void shutdown()等全部任…

前端,关于一个骚气的页面阅读定位图(菜单)

之前在网上看到一个特别骚气的页面阅读定位菜单&#xff0c;今天给大家分享一下原理&#xff0c;先看效果图&#xff1a; 这是我之前浏览联想官网上看到的一个效果图&#xff0c;觉得相当骚气。然后我把他的背景图扣下来&#xff0c;也做了一个&#xff0c;看看效果。 他的实现…

接口自动化测试总结

一、什么项目适合做自动化测试&#xff1f; 软件需求变动不频繁 测试脚本的稳定性决定了自动化测试的维护成本。如果软件需求变动过于频繁&#xff0c;测试人员需要根据变动的需求来更新测试用例以及相关的测试脚本&#xff0c;而脚本的维护本身就是一个代码开发的过程&#x…

【SpringCloudAlibaba】Seata分布式事务使用

文章目录 分布式事务问题示例Seata概述、官网一个典型的分布式事务过程处理过程全局GlobalTransactional分布式交易解决方案流程图 Seata安装下载修改conf目录下的application.yml配置文件dashboard demo 分布式事务问题示例 单体应用被拆分成微服务应用&#xff0c;原来的三个…

详解Transformer中的Encoder

一.Transformer架构 左半边是Encoder&#xff0c;右半边是Decoder。 二.Vision Transformer Vision Transformer取了Transformer的左半边。包含 Input EmbeddingPositional Encoding多头注意力机制 Add & Norm(前馈网络)Feed Forward Add & Norm 2.1 Input Embe…