React Hooks全部总结

Hooks 概念理解

学习目标: 理解 Hooks 的概念及解决的问题

  1. 什么是 hooks

    hooks 的本质: 一套能够使函数组件更强大、更灵活的(钩子)

React 体系里组件分为类组件和函数组件
多年使用发现,函数组件是一个更加匹配 React 的设计理念UI = f(date),也更加有利于逻辑拆分与重用的组件表达形式,而先前组件是不可以有自己的状态的。为了让函数组件可以拥有自己的状态,所以从 react v16.8 开始,加入了 hooks
注意点:

  1. 有了 Hooks 之后,为了兼容老版本,class 类组件并没有被移除,两者都可以使用
  2. 有了 Hooks 之后,不能在把函数成为无状态组件了,因为 Hooks 为函数组件提供了状态
  3. Hooks 只能在函数组件中使用
  4. Hooks 解决了什么问题
    Hooks 的出现解决了两个问题 1.组件的逻辑复用
  5. 组件逻辑复用
    在 Hooks 出现之前,react 先后尝试了 mixin 混入、HOC 高阶组件、render-props 等模式但是都有各自的问题,比如 mixin 的数据来源不清、高阶组件的嵌套问题等
  6. class 组件自身的问题
    class 组件过于厚重,大而全,提供了很多东西,有很高的学习成本,比如繁多的生命周期、this 指向问题等,而更多时候需要轻快的使用组件
  7. Hooks 优势
  8. 告别那一理解的 class
  9. 解决业务逻辑难以拆分的问题
  10. 使状态逻辑复用变的简单
  11. 函数组件在设计思想上与 react 的理念契合

useState

  1. 基础使用
    学习目标: 能够学会 useState 的基础用法
    作用: useState 为函数组件提供状态(state)
    使用步骤:
  2. 导入useState函数
  3. 调用useState函数,并传入状态初始值
  4. useState函数的返回值中,拿到状态和修改状态的方法
  5. 在 JSX 中展示状态
  6. 调用修改状态的方法更新状态
    代码实现:
import { useState } from 'react'
function App() {
  const [count, setCount] = useState(0)
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>{count}</button>
    </div>
  )
}
export default App

状态读取和修改

const [count, setCount] = useState(0) // 解构赋值 useState 返回值是一个数组

  1. useState 传过来的参数 作为 count 的初始值
  2. [count, setCount] 名字可以自定义保持语义化顺序不可以变 第一个参数是数据状态 第二个参数是修改数据的方法
  3. setCount 函数用来修改 count 依旧保持不能直接修改原值还是生成一个新值替换原值 setCount(基于运算得到的新值)
  4. count 和 setCount 是一对 是绑在一起的 setCount 只能用来修改对应的 count 值

组件的更新过程

学习目标: 能够理解使用 Hooks 之后组件的更新状态
函数组件使用 useState hook 后的执行过程,以及状态值的变化

  • 组件第一次渲染
    1. 从头开始执行该组件中的代码逻辑
    2. 调用useState(0)将传入参数作为状态初始值,即:0
    3. 渲染组件,此时,获取到的状态 count 值为:0
  • 组件第二次渲染 1. 点击按钮,调用setCount(count +1)修改状态,因为状态发生改变,所以该组件会重新渲染 2. 组件重新渲染时,会再次执行组件中的代码逻辑 3. 再次调用setCount(0),此时 React 内部会拿到最新的状态值而非初始值 4. 再次渲染组件时获取到的状态 count 值为:1
    注意:useState 的初始值只有在组件第一次渲染时生效,以后的每一次渲染,useState 获取到的都是最新的状态值

使用规则

学习目标: 能够记住 useState 的使用规则

  1. useState函数可以执行多次,每次执行互相独立,每调用一次为函数组件提供一个状态
function List() {
  // 字符串状态值
  const [name, setName] = useState('cp')
  // 数组状态值
  const [list, setList] = useState([])
}
  1. useState 注意事项
  2. 只能出现在函数组件中
  3. 不能嵌套在 if、for、其他函数中(react 按照 hooks 的调用顺序识别每一个 hook)
let num = 1
function List() {
  num++
  if (num / 2 === 0) {
    const [name, setName] = useState('cp')
  }
  const [list, setList] = useState([])
}
// 两个hook的顺序不是固定的,这是不可以的
  1. 可以通过开发者工具查看 hooks 状态
    代码示例:
import { useState } from 'react'
function App() {
  const [count, setCount] = useState(0)
  const [show, setShow] = useState(false)
  const [list, setList] = useState([])
  function test() {
    setShow(!show)
    setList([1, 2, 3, 4])
    console.log(show, list)
  }
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>count:{count}</button>
      <button onClick={test}>
        show:{show ? 'true' : 'false'}---list:{list}
      </button>
    </div>
  )
}
export default App

useEffect 函数

基础使用
  1. 理解函数副作用
    学习目标: 能够理解函数副作用的概念
    什么是函数副作用:
    副作用是相对于主作用来说的,一个函数除了主作用,其他的作用就是副作用,对于 React 组件来说主作用是根据数据(state\props)渲染 UI,除此之外都是副作用(比如,手动修改 DOM)
    常见副作用:
  2. 数据请求 ajax
  3. 手动修改 DOM
  4. localstorage 操作

    useEffect 函数的作用就是为 React 函数组件提供副作用处理

  5. 基础使用
    学习目标: 能够学会 useEffect 的基础用法并且掌握默认的执行时机
    作用 为 React 函数组件提供副作用处理
    使用步骤:
  6. 导入useEffect函数
  7. 调用useEffect函数,并传入回调函数
  8. 在回调函数中编写副作用处理(DOM 操作)
import { useState, useEffect } from 'react'
function App() {
  const [count, setCount] = useState(0)
  useEffect(() => {
    document.title = count
  })
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>count:{count}</button>
    </div>
  )
}
export default App
依赖项控制执行时机
  1. 默认状态(无依赖项) 组件初始化时先执行一次 等每次数据修改更新再次执行
useEffect(() => {
  console.log('副作用执行了')
})
  1. 添加空数组依赖项 组件只在首次渲染时执行一次 其余时间不执行
useEffect(() => {
  console.log('副作用执行了')
}, [])
  1. 添加特定依赖项 副作用函数在首次渲染时执行,在依赖项发生变化时再次执行
import { useState, useEffect } from 'react'
function App() {
  const [count, setCount] = useState(0)
  const [name, setName] = useState('cp')

  useEffect(() => {
    console.log('副作用执行了')
    document.title = count
  }, [count, name])
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>count:{count}</button>
      <button onClick={() => setName('hs')}>name:{name}</button>
    </div>
  )
}
export default App

注意事项: 只要在 useEffect 回调函数中用到的数据(比如,count)就是依赖数据,就应该出现在依赖项数组中,如果不添加依赖项就会有 bug 出现

useState - 回调函数的参数

学习任务: 能够理解 useState 回调函数作为参数的使用场景
使用场景:
参数只会在组建的初始值渲染中起作用,后续渲染时会被忽略,若果初始 State 需要通过计算才能获得,则可以使用一个回调函数,在函数中计算并返回 State,此函数只在初始渲染中起作用
语法

const [name,setName] = useState(()=>{    //编写组算逻辑    return "计算之后的结果"})

语法规则:

  1. 回调函数 return 出去的值将作为 name 的初始值
  2. 回调函数中的逻辑只会在组建初始化的时候执行一次
    语法选择:
  3. 如果就是初始化一个普通的数据,直接使用useState(普通数据) 即可
  4. 如果要初始化的数据无法直接得到需要通过计算才能获取到,使用useState(()=>{})
    代码实现:
import { useState } from 'react'
function getDefaultValue() {
  for (let i = 1; i < 10000; i++) {}
  return '10'
}
function Counter(props) {
  const [count, setCount] = useState(() => {
    return getDefaultValue()
  })
  return <button onClick={() => setCount(count + 1)}>{count}</button>
}
function App() {
  return (
    <div>
      <Counter count={10} />
      <Counter count={20} />
    </div>
  )
}
export default App

useEffect - 清理副作用

学习目标: 能够掌握清理 useEffect 的方法
使用场景:
在组件被销毁时,如果有些副作用需要被清理,就可以使用此语法,比如常见的定时器
语法及规则

useEffect(() => {
  console.log('副作用函数被执行')
  //副作用函数的执行时机为:在下一次副作用函数执行之前
  return () => {
    console.log('清理副作用的函数被执行了')
    // 在这里写清理副作用的代码
  }
})

定时器案例代码实现:

import { useState, useEffect } from 'react'
function Test() {
  useEffect(() => {
    let time1 = setInterval(() => {
      console.log('定时器执行了')
    }, 1000)
    return () => {
      //清理定时器
      clearInterval(time1)
    }
  }, [])
  return <div>this is Test</div>
}
function App() {
  const [flag, setFlag] = useState(true)
  return (
    <div>
      {flag ? <Test /> : null}
      <button onClick={() => setFlag(!flag)}>switch</button>
    </div>
  )
}
export default App

useEffect - 发送网络请求

学习目标: 能够掌握使用 useEffect hook 发送网络请求
使用场景: 如何在 useEffect 中发送网络请求,并且封装同步 async await 操作
语法要求: 不可以直接在 useEffect 的回调函数外层直接包裹 await,因为异步会导致清理函数无法立即返回

useEffect(async () => {
  const res = await axios.get('http://geek.itheima.net/v1_0/channels')
  console.log(res)
}, [])

正确写法:

useEffect(()=>{
  async function fetchDate(){
    const res = await axios.get('http://geek.itheima.net/v1_0/channels)
    console.log(res)
  }
},[])

useRef

学习目标: 能够掌握 useREf 获取真实 DOM 或组件实例的方法
使用场景: 在函数组件中获取真实的 DOM 元素对象或者组件对象
使用步骤

  1. 导入useRef函数
  2. 执行useRef函数并传入 null,返回值为一个对象,内部有一个 current 属性存放拿到的 DOM 对象(组件实例)
  3. 通过 ref 绑定要获取的元素或者组件
    代码示例
import React, { useState, useEffect, useRef } from 'react'
class TestC extends React.Component {
  state = { name: 'testName' }
  getName = () => {
    return 'this is child Test'
  }
  render() {
    return <div>我是类组件</div>
  }
}
function App() {
  const TestRef = useRef(null)
  const h1Ref = useRef(null)
  useEffect(() => {
    console.log(TestRef.current)
    console.log(h1Ref.current)
  })
  return (
    <div>
      <TestC ref={TestRef}></TestC>
      <h1 ref={h1Ref}>This is h1</h1>
    </div>
  )
}
export default App

useContext

学习目标: 能够掌握hooks下的Context使用方法
在这里插入图片描述

实现步骤:

  1. 使用createContext创建Context对象
  2. 在顶层组件通过Provider提供数据
  3. 在底层组件通过useContext函数获取数据
    代码实现:
import React, { createContext, useState, useContext } from "react"
const Context = createContext()
function ComA () {
  const count = useContext(Context)
  return (
    <div>
      this is ComA
      App传过来的数据{count}
      <ComC />
    </div>
  )
}
function ComC () {
  const count = useContext(Context)
  return (
    <div>
      this is ComC
      App传过来的数据{count}
    </div>
  )
}
function App () {
  const [count, setCount] = useState(20)
  return (
    <Context.Provider value={count}>
      <div>
        <ComA />
        <button onClick={() => { setCount(count + 1) }}>+</button>
      </div>
    </Context.Provider>
  )
}
export default App

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

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

相关文章

百度百科词条创作技巧分享,提高创建成功率

我们在百度引擎上搜索一些品牌&#xff0c;很快就能看到品牌的百科内容。我们也可以通过百科快速了解品牌的方方面面&#xff0c;也可以相信品牌有很强的实力。从这几点来看&#xff0c;朋友们可以知道百科词条的重要性&#xff0c;我们可以在以下时间继续了解相关的事情。 1、…

【OceanBase诊断调优】—— 敏捷诊断工具obdiag一键分析OB集群日志设计与实践

最近总结一些诊断OCeanBase的一些经验&#xff0c;出一个【OceanBase诊断调优】专题&#xff0c;也欢迎大家贡献自己的诊断OceanBase的方法。 1. 前言 obdiag定位为OceanBase敏捷诊断工具。1.2版本的obdiag支持诊断信息的一键收集&#xff0c;光有收集信息的能力&#xff0c;…

蓝桥杯单片机快速开发笔记——PCF8591电压信号探测器(可调电阻Rb2电压)和采样光敏电阻

一、原理图 此处考点分析&#xff1a;可能会在引用iic文件时需要自己在头文件定义SCL/SDA sbit sda P2^1; sbit scl P2^0; 二、思维导图 三、代码示例 #include "iic.h" #include "smg.h"unsigned int adc1_value 0; //AIN1的采样数据 float adc…

2024,这些优质可视化大屏素材,承包你一整年的可视化项目

可视化设计一直以来是个难题。如果不知道方法论、没有相关资源&#xff0c;那即使熬了几个大夜&#xff0c;掉了一地头发&#xff0c;设计出来了的东西也只会落个遭人嫌弃的下场。 所以&#xff0c;为了帮助大家提高可视化开发效率&#xff0c;快速制作出美观的可视化效果&…

luceda ipkiss教程 63:器件端口延伸ExtendPorts

案例分享&#xff1a;通过picazzo3库中的ExtendPorts函数实现器件的端口延伸 如&#xff1a; 所有代码如下&#xff1a; from si_fab import all as pdk from ipkiss3 import all as i3 from picazzo3.container.extend_ports import ExtendPorts# Building the MMI PCell wi…

C语言例:整型常量025,求解十进制和十六进制

1. 八进制数的每一位乘以对应的权值&#xff08;8的幂&#xff09;&#xff0c;然后将结果相加&#xff0c;得到十进制数。 025 21 2.八进制先转二进制&#xff08;一变三&#xff09;&#xff0c;再二进制转十六进制&#xff08;四合一&#xff09; 025 0001 0101 0…

Unity类银河恶魔城学习记录11-1 p103 Item源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili ItemData.cs using System.Collections; using System.Collections.Generi…

vue3+ts动态表单渲染,antd的useForm改造

let fieldList: any getFormFields(fieldInfo.coreNavigationList[0].list[0].list,fieldInfo.positionCodeRespVO,isCanBeUpdateProcess.value,isDetail.value 1); fieldInfo数据格式&#xff1a; {"name": "默认模板","status": "ENA…

03、判断和循环

三、判断与循环 文章目录 三、判断与循环顺序结构分支结构If语句在程序中就是用来判断的switch 循环结构forwhiledo while 顺序结构 顺序结构是Java程序默认的执行流程&#xff0c;按照代码的先后顺序&#xff0c;从上到下依次执行。 分支结构 If语句在程序中就是用来判断的 …

opc客户端

支持opc&#xff0c;da&#xff0c;ua通信&#xff08;匿名登陆及用户登陆&#xff09; 支持批量节点数据监听&#xff0c;当数据有变化时更新 支持单个节点读取和写入 KeepServer做为modbus server keepserver通信配置 https://blog.csdn.net/xiaochenXIHUA/article/detail…

高通推出第三代骁龙8s移动平台,首款终端预计将于3月面市

2024年3月18日&#xff0c;圣迭戈——高通技术公司今日宣布推出第三代骁龙8s移动平台&#xff0c;为更多Android旗舰智能手机带来骁龙8系平台上最广受欢迎的特性&#xff0c;实现非凡的顶级移动体验。这款全新旗舰级平台的主要特性包括支持强大的终端侧生成式AI功能、始终感知的…

操作系统核心知识点大梳理

计算机结构 现代计算机模型是基于-冯诺依曼计算机模型 计算机在运行时&#xff0c;先从内存中取出第一条指令&#xff0c;通过控制器的译码&#xff0c;按指令的要求&#xff0c;从存储器中取出数据进行指定的运算和逻辑操作等加工&#xff0c;然后再按地址把结果送到内存中去…

【Leetcode-21合并两个有序链表】

题目详情&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2 […

由浅到深认识C语言(4):数组

该文章Github地址&#xff1a;https://github.com/AntonyCheng/c-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.csdn…

市场复盘总结 20240318

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 36% 最常用…

【LeetCode每日一题】303. 区域和检索 - 数组不可变

文章目录 [303. 区域和检索 - 数组不可变](https://leetcode.cn/problems/range-sum-query-immutable/)思路&#xff1a;前缀和代码&#xff1a; 303. 区域和检索 - 数组不可变 思路&#xff1a;前缀和 1.因为要根据给出的两个索引&#xff0c;来返回索引区间的和 2.创建一个…

选Gitee还是GitHub?

2024年3月18日&#xff0c;周一晚上 我选择GitHub 因为GitHub可以无限创建仓库

电脑装win11(作si版)

装win11经历 前言&#xff1a;因为我的u盘今天到了&#xff0c;迫不及待试试装机 然后在一系列准备好工具后&#xff0c;便是开始拿学校的机房电脑来试试手了~~ 前期准备 下载好win11镜像&#xff08;可以去微软官网下载&#xff09; 下载Rufus工具 https://www.lanzoue.com/…

Qt学习--继承(并以分文件实现)

基类 & 派生类 一个类可以派生自多个类&#xff0c;这意味着&#xff0c;它可以从多个基类继承数据和函数。定义一个派生类&#xff0c;我们使用一个类派生列表来指定基类。类派生列表以一个或多个基类命名。 总结&#xff1a;简单来说&#xff0c;父类有的&#xff0c;子…

【Chapter1】操作系统概述,计算机操作系统教程,第四版,左万利,王英

文章目录 一、操作系统的基本概念1.1操作系统的层次结构1.2操作系统的运行视图1.3操作系统的概念(定义)1.4操作系统的功能和目标1.4.1操作系统的功能和目标——作为系统资源的管理者1.4.2操作系统的功能和目标——向上层提供方便易用的服务1.4.2.1GUI&#xff1a;图形化用户接口…