react笔记_07 hooks

news2025/1/15 23:26:39

什么是hook?

以前我们称函数组件为简单组件,因为函数组件是无状态的(没有state)。

而在React 16.8版本增加了 Hook,它可以让你在不编写 class 组件的情况下,也就是我们可以在函数组件中使用 state 以及其他的 React 特性。

Hook 不能在 class 组件中使用 —— 这使得你不使用 class 也能使用 React。

hook使用规则

  • 不要在循环,条件或嵌套函数中调用 Hook,确保总是在你的 React 函数的最顶层以及任何 return 之前调用他们。
  • 只在 React 函数中调用 Hook,不要在普通的 JavaScript 函数中调用 Hook。

useState

useState 是我们要学习的第一个 “Hook”。

举例说明

在这里插入图片描述
现在有如上需求:一个定时器 当点击 “点我num++” 按钮时,将num的值+1。

若是我们使用class组件如下

import React, { Component } from 'react'
export default class New extends Component {
  state = { num: 0 } // 初始化数据
  render() {
    const { num } = this.state
    return (
      <div>
        {num}
        <button onClick={this.editNum}>点我num++</button>
      </div>
    )
  }
  editNum = () =>{
    const { num } = this.state
    this.setState({num: num+1}) // 通过setState更新数据
  }
}

而在函数组件中,我们没有 this,所以我们不能分配或读取 this.state。我们直接在组件中调用 useState Hook.

import React, { useState } from 'react'
export default function New2 (){
 const [num, setNum] = useState(0) // 初始化数据
 const editNum = () =>{
   setNum(num+1) // 更新数据
 }  
 return(
   <div>
     {num}
     <button onClick={editNum}>点我num++</button>
   </div>
 )
}

语法

1. 定义一个 state变量
  useState(initialState)

通过useState函数初始化数据

  • 参数:initialState为初始 state 值,不同于 class 的是,我们可以按照需要使用数字或字符串对其进行赋值,而不一定是对象。

  • 返回值:返回值为一个数组,数组中存在两个元素,第一个元素为当前state,第二个元素为更新此state的函数。

  • 该函数的作用是 定义一个 “state 变量”。这是一种在函数调用时保存变量的方式 。一般来说,在函数退出后变量就会”消失”,而 state 中的变量会被 React 保留

2. 读取state变量
const [num] = this.useState(0)

console.log(num) // 使用时直接当作变量使用即可
3. 更新state变量值
const [num, numState] = this.useState(0)

// numState是用于更新的函数
numState(value) // value可以为一个想要更新的值也可以是一个函数

// 传入一个值 -> 该值作为更新值去进行更新
newState(1) // 会将num值变为1

// 传入一个函数 ->  会自动调用该函数并将上一次的state值作为参数传入
newState(prestate => return prestate+1 ) // 会将num的值在当前基础上加1

如果新的 state 需要通过使用先前的 state 计算得出,对于同步更新来说 传值或者是函数是没有区别的,但是对于异步更新来说更推荐使用 函数,使用以下例子进行说明:

  • 参数为一个值
    import React, { useState } from 'react'
    export default function New2 (){
      const [num, setNum] = useState(0)
      const editNum = () =>{
        setTimeout(()=>{
          setNum(num+1)
        },1000)
      }  
      return(
        <div>
          {num}
          <button onClick={editNum}>点我num++</button>
        </div>
      )
    }
    
  • 参数为一个函数
    import React, { useState } from 'react'
    export default function New2 (){
      const [num, setNum] = useState(0)
      const editNum = () =>{
        setTimeout(()=>{
          setNum(preState=> preState+1 )
        },1000)
      }  
      return(
        <div>
          {num}
          <button onClick={editNum}>点我num++</button>
        </div>
      )
    }
    

当我设置为异步更新,点击按钮延迟到1s之后去更新数据,当我快速点击按钮时,也就是说在1s多次去触发更新,但是只有一次生效,因为 count 的值是没有变化的。

当使用函数式更新 state 的时候,这种问题就没有了,因为它可以获取之前的 state 值,也就是代码中的 preState 每次都是最新的值

useEffect

Effect Hook 可以让你在函数组件中执行副作用操作。

语法

import React, { useEffect } from 'react'
useEffect(()=>{
  // 逻辑代码
},[])
  • 第一个参数是一个函数
  • 第二个参数为一个数组(可省略)

执行时机

Every time your component renders, React will update the screen and then run the
code inside useEffect.

默认情况下 useEffect在每次render之后执行
若是不想每次render之后执行,可以接收第二个参数来控制跳过执行。

跳过 Effect
[1] 每次render之后执行

若是第二个参数不传,则useEffect将每次render之后都会执行,相当于omponentDidMount,componentDidUpdate两个生命周期函数。

useEffect(()=>{
  console.log('执行了')
})

上述代码在 每次render之后都会执行。

[2] 仅在挂载时执行

若是第二个参数传入一个空数组,则useEffect将仅在初始化时执行,相当于omponentDidMount。

useEffect(()=>{
  console.log('执行了')
},[])

上述代码仅仅在初始化时执行。

[3]仅当某个值变化时执行

若是第二个参数传入 带有元素的数组,则useEffect将仅在初始化元素的值发生变化时执行

useEffect(()=>{
  console.log('执行了')
},[num])

上述代码仅在初始化和num的值发生变化时执行。

useEffect(()=>{
  console.log('执行了')
},[num,value])

上述代码仅在初始化和 num或value值发生变化时执行。

注意
若是(第二个参数)数组元素中存在引用类型,就应该在第一个参数也就是执行的副作用函数中不要用setState相关的代码,否则容易引起死循环!

[4] 在组件卸载时执行

在useEffect的第一个参数中,若是存在return,则return的函数将会在组件卸载时执行

举例说明

useEffect(() => {
  window.a = 100;
  return ()=>{window.a = 0};
}, []);

上述代码在组件挂载时执行 代码window.a = 100; 在组件卸载时执行window.a = 0

现象- useEffect在初始化时会执行两次

在写项目时,发现初次渲染useEffect执行了两次,在网上搜了一下发现这是React18 新加的特性

  • 这是 React18 才新增的特性。
  • 仅在开发模式(“development”)下,且使用了严格模式(“Strict Mode”)下会触发; 生产环境(“production”)模式下和原来一样,仅执行一次。
  • 之所以执行两次,是为了模拟立即卸载组件和重新挂载组件。为了帮助开发者提前发现重复挂载可能会造成的 Bug。 同时,也是为了以后 React的新功能做铺垫 -> 未来会给 React 增加一个特性,允许 React 在保留状态的同时,能够做到仅仅对UI部分的添加和删除.让开发者能够提前习惯和适应,做到组件的卸载和重新挂载之后, 重复执行 useEffect的时候不会影响应用正常运行。

清除effect

有时候,我们只想在 React 更新 DOM 之后运行一些额外的代码。比如发送网络请求,手动变更 DOM,记录日志,这些都是常见的无需清除的操作。因为我们在执行完这些操作之后,就可以忽略他们了。还有一些副作用是需要清除的。例如订阅外部数据源。这种情况下,清除工作是非常重要的,可以防止引起内存泄露!

举例说明-清除事件监听

useEffect(() => {
  function handleScroll(e) {
    console.log(e.clientX, e.clientY);
  }
  window.addEventListener('scroll', handleScroll);
  return () => window.removeEventListener('scroll', handleScroll);
}, []);

参考文档

  • 官方文档
  • useState用法指南
  • 关于useEffect的第二个参数解读
  • React18的useEffect会执行两次

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

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

相关文章

5G无线技术基础自学系列 | 5G服务完整性KPI

素材来源&#xff1a;《5G无线网络规划与优化》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 5G服务完整性KPI用来评估5G RAN中终端用…

java: 无效的目标发行版: 17 新建springBoot项目

问题 java: 无效的目标发行版: 17 详细问题 新建springBoot项目&#xff0c;对数据库配置后启动项目&#xff0c;控制台报错 java: 无效的目标发行版: 17 如下图 解决方案 查看JDK版本 &#xff08;事实上&#xff0c; 该步骤查看本机的已配置环境变量的JDK版本&#xff…

Python基础(十)模块与包

目录 1. 简介 1.1 模块 1.2 包 2. 使用 2.1 创建 2.2 引用 1. 简介 1.1 模块 Python 中一个以 .py 结尾的文件就是一个模块&#xff0c;模块中定义了变量、函数等来实现一些类似的功能。Python 有很多自带的模块&#xff08;标准库&#xff09;和第三方模块&#xff0c…

UMC产品UI升级说明

随着产品功能的逐渐完善&#xff0c;一款好的产品需要不断地打磨才能变得更完整、更稳定。所以&#xff0c;UMC作为数通畅联的核心产品&#xff0c;为了满足更多的需求&#xff0c;更好的视觉效果和体验感&#xff0c;一直都在不断地完善迭代。 本次升级主要是针对整体页面进行…

实现股票交易c接口​​​​​​​需要的注意事项有哪些?

实现股票交易c接口需要的注意事项有哪些&#xff1f;最近有很多朋友问小编这个问题&#xff0c;小编今天就说说&#xff01; 在基类列表中包含接口名称 为每一个接口的成员提供实现 如果类从基类继承并实现了接口&#xff0c;基类列表中的基类名称必须放在所有接口之前。(一个…

PMAC的PVT功能实现解析笔记

从上图中我们可以得到如下信息&#xff1a; 速度截面是一个抛物线 P0P_0P0​、V0V_0V0​是上一次指定的&#xff0c;P1P_1P1​、V1V_1V1​是当前期望的&#xff0c;TA是当前期望的运动时间 A0A_0A0​是上一次计算的&#xff0c;A1A_1A1​是当前计算的&#xff0c;加加速度dA/…

使用 x-sheet 构建在线疫情高峰预测数据表

背景 最近&#xff0c;一位大数据专家通过百度“发烧”的搜索指数、公开的疫情感染人数等指标&#xff0c;计算出每个城市的“超额发烧搜索指数累计面积”&#xff0c;并且通过城市的搜索指数累计增长、累计速度&#xff0c;就可以算出现在每一个有疫情的城市疫情大概的达峰时…

MyBatis-Plus保姆级快速上手教程

为简化开发而生 Mybatis简化JDBC操作 MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 1、特性 无侵入&#xff1a;只做增强不做改变&#xff0c;引入它不会对…

都28了,半路转行学编程还来得及吗?

很多新来的粉丝&#xff0c;经常会问到&#xff1a;“我现在xx岁了&#xff0c;学编程晚吗?"&#xff0c;“程序员是不是吃青春饭啊&#xff0c;我都没有青春了&#xff0c;还能找到工作吗&#xff1f;”... 其实这类的问题&#xff0c;我以前都已经整理过文章&#xff0…

正点原子-Linux嵌入式开发学习-第二期05

第十三讲&#xff1a;按键实验 1&#xff1a;原理图分析&#xff0c;按键按下低电平进入&#xff0c;不按下高电平 对应的端口为&#xff1a;GPIO1_IO18 复制上一次工程&#xff0c;记得make clean清除上一次的文件 程序编写 1&#xff1a;新建key文件夹并新建bsp_key.c和bsp_…

Scala 高阶函数(二)

一、scala自带高阶函数 概述&#xff1a;可以接收一个函数的函数就是高阶函数&#xff0c;又称为算子 1。map&#xff1a; 将集合中的每一个元素通过指定功能(函数)映射(转换)成新的结果集 val list1 List(1,2,3) val list2 list1.map(v>v*2) println(list2) //List…

[第十二届蓝桥杯/java/算法]D——相乘

&#x1f9d1;‍&#x1f393;个人介绍&#xff1a;大二软件生&#xff0c;现学JAVA、Linux、MySQL、算法 &#x1f4bb;博客主页&#xff1a;渡过晚枫渡过晚枫 &#x1f453;系列专栏&#xff1a;[编程神域 C语言]&#xff0c;[java/初学者]&#xff0c;[蓝桥杯] &#x1f4d6…

C#获取计算机硬件的参数信息

2019年的时候用PowerBuilder写过一个计算机信息收集小程序&#xff0c;《计算机信息收集小程序》&#xff0c;当时是查注册表来实现的。 还可以通过对windows的API调用来做&#xff0c;这个稍微有点麻烦。 使用C#也可以通过三种方式来实现&#xff0c;分别是读取注册表、window…

import语句写烦了,怎么办?

每次写数据相关的代码时都会习惯性地先写一堆import语句&#xff0c;不管用得到用不到&#xff0c;先在文首默一遍再说。 或者&#xff1a; ❞虽说CtrlC和CtrlV也很方便&#xff0c;但是每次都要先“抄一次”也很烦。 那么有没有什么好的解决办法&#xff1f; Python有一个模…

《码出高效:java开发手册》六-数据结构与集合(一)

前言 本章主要是讲数据结构与集合&#xff0c;这章内容涉及到非常基础的知识&#xff0c;内容相对较多&#xff0c;首先从数组讲起&#xff0c;引申到集合框架&#xff0c;之后再到集合源码&#xff0c;最后介绍了高并发集合框架 集合 集合在代码中是collection&#xff0c;…

智牛股_第8章_Sentinel

智牛股_第8章_Sentinel 文章目录智牛股_第8章_Sentinel学习目标第1章 Sentinel集成使用1. 目标2. 步骤3. 实现3.1 生产环境最优配置方案3.2 用户服务集成3.3 熔断规则配置3.4 启动Sentinel监控台3.5 功能使用验证4. 总结第2章 用户注册功能1. 目标2. 步骤3. 实现3.1 用户注册流…

flstudio21版本有什么新功能及免费新插件

全能数字音乐工作站&#xff08;DAW&#xff09;编曲、剪辑、录音、混音&#xff0c;23余年的技术积淀和实力研发&#xff0c;FL Studio已经从电音领域破圈&#xff0c;成功蜕变为瞩目的全能DAW&#xff0c;把电脑变成全功能音乐工作室&#xff0c;接下来我们会为您一一展示 2…

Prometheus Operator实战—— Prometheus、Alertmanager、Grafana 监控RockectMq

1. RocketMQ 介绍 RocketMQ 是一个分布式消息和流数据平台&#xff0c;具有低延迟、高性能、高可靠性、万亿级容量和灵活的可扩展性。简单的来说&#xff0c;它由 Broker 服务器和客户端两部分组成&#xff0c;其中客户端一个是消息发布者客户端(Producer)&#xff0c;它负责向…

硬盘恢复工具软件哪个好?分享这些硬盘数据恢复工具软件

您刚刚删除了一些非常重要的文件&#xff01; 不要惊慌……您仍然有很大的机会可以以很少甚至免费的方式取回它们。 我们正在深入研究当今最好的硬盘恢复软件。 我们认为有一个明显的赢家&#xff0c;但我们提供了一些其他选项&#xff0c;以防您需要更高级的功能或使用不同…

四、网络层(三)IPv4

目录 3.1 IPv4地址 3.1.1分类编址 3.1.2子网划分与子网掩码 3.1.3无分类编址CIDR 3.1.4网络地址转换&#xff08;NAT&#xff09; 3.2 IPv4分组 3.2.1 IP分组&#xff08;IP数据报&#xff09;的格式 3.2.2 IP数据报分片 3.3 地址解析协议&#xff08;ARP&am…