IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React学习 day-05 -> 正文阅读

[JavaScript知识库]React学习 day-05

day-05

Hooks

Hooks:钩子、钩住,是 React@16.8 提供的新功能。

Hooks作用: 能为函数式组件提供状态和生命周期,Hooks 只能在函数组件中使用

Hooks(提供状态和生命周期)+函数组件(展示内容)

Hooks解决了什么问题

  • 组件的状态逻辑复用问题

    a,在 Hooks 之前,组件的状态逻辑复用经历了:mixins(混入)、HOC(高阶组件)、render props 等模式。

    b,(早已废弃)mixins 的问题:数据来源不清晰;命名冲突。

    c,HOC、render props 的问题:重构组件结构,导致组件形成 JSX 嵌套地狱问题。

  • class组件自身的问题

    a,选择:函数组件和 class 组件之间的区别以及使用哪种组件更合适。

    b,需要理解 class 中的 this 是如何工作的。

    c,同一业务的状态和业务逻辑被拆分到不同位置。

  • 相比于函数组件来说,类组件不利于代码压缩和优化,也不利于TS的类型推导

    # 例如不能把 componentDidMount 压缩成 c
    # 例如写 this 的时候没有提示,因为 this 只有在调用的时候才能确定指向,编写代码期间 TS 是不知道的
    

Hooks 渐进策略

目标

能够了解 Hooks 和之前 class 的写法是可以共存的。

内容

  • 官方没有计划从 React 中移除 class 组件。

  • Hooks 和现有代码可以同时工作,建议渐进式地使用它们。

    a,不推荐:大规模使用 Hooks 直接重构现有组件。

    b,推荐:新功能用 Hooks,Hooks 实现不了的复杂功能,也可以继续用 class。

    c,具体操作,从一些功能简单、非核心功能的组件开始使用 Hooks。

  • 不能在 Hooks 组件中,使用 class 组件相关的 API。

    a,state 与 setState。

    b,钩子函数,componentDidMountcomponentDidUpdatecomponentWillUnmount

    c,this 相关的用法。

  • 原来学习的绝大部分知识点还是要用的。

    a,JSX:{}onClick={handleClick}、条件渲染、列表渲染、样式处理等。

    b,组件:函数组件、组件通讯。

    c,React 开发理念:单向数据流状态提升 等。

    d,解决问题的思路、技巧、常见错误的分析等。

useState 使用

作用:

为函数组件提供状态和修改状态的方法。

使用:

  1. 导入 useState 函数。
  2. 调用 useState 函数,并传入状态的初始值。
  3. useState 函数的返回值中,拿到状态和修改状态的函数。
import React, { useState } from 'react'

export default function App() {
    //参数:代表默认值
    //返回值:数组[初始数据,修改数据的方法]
  const [count, setCount] = useState(0)
  return (
    <div>
      <h2>计数器:{count}</h2>
      <button
        onClick={() => {
          setCount(count + 1)
        }}
      >
        +1
      </button>
    </div>
  )
}

细节

  • 参数:初始状态,比如传入 0 就表示该状态的初始值为 0。
  • 注意:此处的状态可以是任意值(比如,数值、字符串、对象等),注意 class 组件中的 state 必须是对象。
  • 返回值:数组,数组里面包含两个值,状态和修改该状态的方法。
  • 约定:修改状态的方法以 set 开头,后面跟上状态的名称。

注意事项

  • 读取状态

    目前,useState 只能在函数组件内部调用(也可以在后续学习的自定义 Hook 中使用),所以返回的状态也是函数内部的局部变量。

  • 修改状态

    a,setCount(newValue) 是一个函数调用,参数表示新的状态值。

    b,调用该函数后,将使用新的状态值直接替换旧状态。

    c,修改状态后,组件会自动重新渲染。

  • 状态的不可变性(修改状态的时候,要使用新的状态替换掉旧的状态,而不要直接修改原状态)。

import React, { useState } from 'react'

const App = () => {
    const [obj, setObj] = useState({
        count: 0,
    })
    const handleClick = () => {
        // Error
        obj.count++
        setObj(obj)
        // Right
        /* setObj({
            count: obj.count + 1,
        }) */
    }
    return (
        <div>
            <p>{obj.count}</p>
            <button onClick={handleClick}>click</button>
        </div>
    )
}

export default App

useState 与组件更新过程

目标

能够说出使用功能 useState() 之后,组件的更新过程。

内容

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

useState 另一种写法

目标

掌握 useState(回调函数) 的写法。

内容

  • useState(回调函数),回调函数的返回值就是状态的初始值,该回调函数只会触发一次。
useState(() => {
    return 初始值
})
  • 该使用哪种形式?

    a,如果状态就是需要一个普通数据(没有逻辑、无需计算),那么推荐 useState(普通的数据)

    b,如果状态是经过一些计算得到的,此时,推荐使用 useState(回调函数)。因为改回调函数只会执行一次,节省性能。

import React, { useState } from 'react'

export default function App() {
  // let defaultCount = 0
  // console.log(1)
  // for (let i = 1; i < 10000; i++) {
  //   defaultCount += i
  // }
  // const [count, setCount] = useState(defaultCount)
  console.log(1)
  const [count, setCount] = useState(() => {
    let defaultCount = 0
    console.log(2)
    for (let i = 1; i < 10000; i++) {
      defaultCount += i
    }
    return defaultCount
  })
  return (
    <div>
      <h2>计数器:{count}</h2>
      <button
        onClick={() => {
          setCount(count + 1)
        }}
      >
        +1
      </button>
    </div>
  )
}

useState 使用细则

目标

掌握如何为函数组件提供多个状态以及注意点。

内容

  • 如何为函数组件提供多个状态?

    多次调用 useState 即可,每一次调用返回的 [state, setState] 之间,互不影响。

  • useState 的使用细则。

    a,目前,只能直接出现在函数组件中(其他 Hook 也一样)。

    b,不能嵌套在 if/for/其他函数 中!(if 的条件判断、for 循环的次数、函数的调用与否都可能会影响 hook 的顺序)。

    c,React 是按照 Hooks 的调用顺序来识别每一个 Hook,如果每次调用的顺序不同,导致 React 无法知道是哪一个状态和修改状态的方法。

    d,可以通过开发者工具进行查看 React 对 Hook 的管理。

import React, { useState } from 'react'

export default function App() {
    const [num1, setNum1] = useState(0)
    const [num2, setNum2] = useState(3)
    const [num3, setNum3] = useState(6)
    return (
        <div>
            <div>
                num1: {num1}
                <button onClick={() => setNum1(num1 + 1)}>修改 num1</button>
            </div>
            <div>
                num2: {num2}
                <button onClick={() => setNum2(num2 + 1)}>修改 num1</button>
            </div>
            <div>
                num3: {num3}
                <button onClick={() => setNum3(num3 + 1)}>修改 num1</button>
            </div>
        </div>
    )
}

useEffect 副作用介绍

目标

能够说出什么是副作用(side effect)。

内容

  • 类比,对于 999 感冒灵来说。

    a,主作用:用于治疗感冒引起的头痛,发热,鼻塞,流涕,咽痛等。

    b,副作用:可见困倦、嗜睡、口渴、虚弱感。

  • 那组件或一般函数的副作用是什么呢?

    a,组件的副作用:对于 React 组件来说,主作用就是根据数据(state/props)渲染 UI,除此之外都是副作用,比如手动修改 DOM、数据(AJAX)请求、localStorage 操作等。

    b,函数的副作用:如果一个函数修改了其局部环境之外的数据,那么它就被称为有副作用。

  • 关于 useEffect。

    作用:当你想要在函数组件中处理副作用(side effect),就要使用 useEffect 了。

总结

  • 对于 React 组件来说,“主作用”是什么?
  • 常见的有哪些“副作用”?

useEffect 基本使用

目标

能够在函数组件中操作 DOM(处理副作用)。

内容

  • 执行时机:初始化时和数据变化的时候执行。
  • 相当于 class 中的 componentDidMount + componentDidUpdate。

需求

在实际开发中,副作用是不可避免的。

📝 需求:点击按钮,让数字加 1,并把变化后的数字展示在网页标题上。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0tXb4VGg-1639142190748)(react.assets/ifer_useEffect.gif)]

步骤

  1. 初始化时渲染数据到网页标题上。
  2. 当数据变化的时候把变化后的数据渲染到网页标题上。

代码

import React, { useState, useEffect } from 'react'

const App = () => {
    const [count, setCount] = useState(() => 0)
    useEffect(() => {
        // 1. 初始化时执行(componentDidMount)
        // 2. 数据变化的时候执行(componentDidUpdate)
        document.title = count
    })
    return (
        <div>
            <p>{count}</p>
            <button onClick={() => setCount(count + 1)}>click</button>
        </div>
    )
}

export default App

小结

上面 useEffect 的写法相当于 class 组件中哪两个钩子?

useEffect 依赖说明

目标

能够设置 useEffect 的依赖,只在 count 变化时,才执行相应的 effect。

内容

  • 问题:如果组件中还有其他状态,其他状态更新时,刚刚的 effect 回调(修改标题的操作)也会执行。
  • 默认:函数中的任何状态发生更新,useEffect 的回调函数都会执行。
  • 优化:如何跳过不必要的执行,只有在 count 变化时,才执行相应的 effect
  • 操作:第二个参数可以传一个数组,表示只有当数组中的选项/依赖项改变时,才会重新执行该 effect。

问题

import React, { useState, useEffect } from 'react'

const App = () => {
    const [count, setCount] = useState(0)
    const [money, setMoney] = useState(100)
    useEffect(() => {
        console.log('执行了 useEffect ~~~')
        document.title = count
    })
    return (
        <div>
            <p>count: {count}</p>
            <p>money: {money}</p>
            <button onClick={() => setCount(count + 1)}>update count</button>
            <button onClick={() => setMoney(money + 1)}>update money</button>
        </div>
    )
}

export default App

解决

useEffect(() => {
    //初始化和count变化时会走这里
    console.log('执行了 useEffect ~~~')
    document.title = count
}, [count])

小结

useEffect 的第二个参数用来干嘛的?

指定依赖项

useEffect 依赖是一个空数组

目标

通过 useEffect 如何让组件只有在第一次渲染后会执行。

内容

useEffect 的第二个参数,还可以是一个空数组([]),表示只有在组件第一次渲染后执行,一般会进行事件绑定发送请求等。

代码

useEffect(() => {
    const handleResize = () => {}
    window.addEventListener('resize', handleResize)
}, [])

解释

  • 仅相当于 class 组件的 componentDidMount 钩子函数的作用。
  • 和 useState 一样,一个组件中也可以调用多次 useEffect。
  • 推荐:一个 useEffect 只处理一个功能,有多个功能时,使用多次 useEffect。

小结

useEffect 的第二个参数是一个空数组,相当于 class 组件中的那个钩子?

useEffect 不要对依赖项撒谎

目标

能够理解如果不正确使用依赖项可能会带来的问题。

内容

  • useEffect 回调函数中用到的数据(比如前面学习的 count)就是依赖数据,就应该出现在依赖项数组中。
  • 如果 useEffect 回调函数中用到了某个数据,但是没有出现在依赖项数组中,就会导致一些“Bug”出现(例如 useEffect 回调不会执行)!
  • 所以,不要对 useEffect 的依赖撒谎,参考 useEffect 完全指南
import React, { useState, useEffect } from 'react'

const App = () => {
    const [count, setCount] = useState(0)
    useEffect(() => {
        // React Hook useEffect has a missing dependency: 'count'. Either include it or remove the dependency array
        document.title = count
    }, [])
    return (
        <div>
            <p>count: {count}</p>
            <button onClick={() => setCount(count + 1)}>update count</button>
        </div>
    )
}

export default App

小结

能够说出对 useEffect 第 2 个参数几种写法所代表的含义,例如不写第二个参数、写空数组、或者 [count] 分别表示什么意思?

// 触发时机:第一次渲染会执行,任何数据变化导致组件更新时执行,相当于 componentDidMount + ComponentDidUpdate
useEffect(() => {})

// 触发时机:只在组件第一次渲染时执行,相当于 componentDidMount
useEffect(() => {}, [])

// 触发时机:第一次渲染会执行,当 count 变化时会再次执行,相当于 componentDidMount + componentDidUpdate(判断)
useEffect(() => {}, [count])

倒计时

避免闭包产生

import React, { useState } from 'react'

let timer = null
export default function App() {
  const [count, setCount] = useState(10)
  const startTime = () => {
    clearInterval(timer)
    timer = setInterval(() => {
      // console.log(1)
      //此处的count是形参,不是引用的count
      setCount((count) => count - 1)
    }, 1000)
  }
  return (
    <div>
      <h3>{count}</h3>
      <button onClick={startTime}>开启定时器</button>
    </div>
  )
}

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-11 15:37:53  更:2021-12-11 15:39:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:12:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码