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. 调用修改状态的方法更新状态
    代码实现:
js 复制代码
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. 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函数可以执行多次,每次执行互相独立,每调用一次为函数组件提供一个状态
js 复制代码
function List() {
  // 字符串状态值
  const [name, setName] = useState('cp')
  // 数组状态值
  const [list, setList] = useState([])
}
  1. useState 注意事项
  2. 只能出现在函数组件中
  3. 不能嵌套在 if、for、其他函数中(react 按照 hooks 的调用顺序识别每一个 hook)
js 复制代码
let num = 1
function List() {
  num++
  if (num / 2 === 0) {
    const [name, setName] = useState('cp')
  }
  const [list, setList] = useState([])
}
// 两个hook的顺序不是固定的,这是不可以的
  1. 可以通过开发者工具查看 hooks 状态
    代码示例:
js 复制代码
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 操作)
js 复制代码
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. 默认状态(无依赖项) 组件初始化时先执行一次 等每次数据修改更新再次执行
js 复制代码
useEffect(() => {
  console.log('副作用执行了')
})
  1. 添加空数组依赖项 组件只在首次渲染时执行一次 其余时间不执行
js 复制代码
useEffect(() => {
  console.log('副作用执行了')
}, [])
  1. 添加特定依赖项 副作用函数在首次渲染时执行,在依赖项发生变化时再次执行
js 复制代码
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,此函数只在初始渲染中起作用
语法

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

语法规则:

  1. 回调函数 return 出去的值将作为 name 的初始值
  2. 回调函数中的逻辑只会在组建初始化的时候执行一次
    语法选择:
  3. 如果就是初始化一个普通的数据,直接使用useState(普通数据) 即可
  4. 如果要初始化的数据无法直接得到需要通过计算才能获取到,使用useState(()=>{})
    代码实现:
js 复制代码
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 的方法
使用场景:

在组件被销毁时,如果有些副作用需要被清理,就可以使用此语法,比如常见的定时器
语法及规则

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

定时器案例代码实现:

js 复制代码
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,因为异步会导致清理函数无法立即返回

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

正确写法:

js 复制代码
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 绑定要获取的元素或者组件
    代码示例
js 复制代码
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函数获取数据
    代码实现:
js 复制代码
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
相关推荐
恋猫de小郭36 分钟前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端