• React-hooks


    Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

    Hooks 的本质:一套能够使函数组件更强大,更灵活的“钩子”。

    注意点:

    1. 有了 hooks 之后,为了兼容老版本,class 类组件并没有被移除,俩者都可以使用;
    2. 有了 hooks 之后,不能再把函数组件称为无状态组件了,因为 hooks 为函数组件提供了状态;
    3. hooks 只能在函数组件中使用。

    useState

    useState 为函数组件提供状态(state)

    使用步骤

    1. 导入 useState 函数
    2. 调用 useState 函数,并传入状态的初始值
    3. 从 useState 函数的返回值中,拿到状态和修改状态的方法
    4. 在JSX中展示状态
    5. 调用修改状态的方法更新状态

    代码实现

    1. // 从 react 中解构出 useState
    2. import { useState } from 'react'
    3. function App () {
    4. // 调用 useState 函数,并传入状态的初始值
    5. const [count, addCount] = useState(0)
    6. // 这里的 count 是状态,addCount 是更新状态的方法
    7. return (
    8. <div className="App">
    9. <p>count: {count}p>
    10. {/* 通过点击按钮调用修改状态的方法更新状态 */}
    11. <button onClick={() => addCount(count + 1)}>count+1button>
    12. div>
    13. )
    14. }

    修改状态

    1. addCount 是一个函数,参数表示最新的状态值
    2. 调用该函数后,将使用新值替换旧值
    3. 修改状态后,由于状态发生变化,会引起视图变化

    使用规则

    1.useState 函数可以执行多次,每次执行互相独立,每调用一次为函数组件提供一个状态;

    1. function List(){
    2. // 以字符串为初始值
    3. const [name, setName] = useState('zs')
    4. // 以数组为初始值
    5. const [list,setList] = useState([])
    6. }

    2. const [状态, 更新状态的方法] = useState(初始值),注:这里的“初始值”可以是一个函数(只要函数 return 一个值就行),所以,如果初始值是需要通过一定的逻辑(比如计算)才能得到,可以写一个方法,让该方法 return 初始值即可;

    3.useState 注意事项

    • useState 提供的状态是函数内部的局部变量,可以在函数内的任意位置使用;
    • useState 的初始值(参数)只会在组件第一次渲染时生效。也就是说,以后的每次渲染,useState 获取到都是最新的状态值,React 组件会记住每次最新的状态值;
    • 调用 useState() 的语句只能出现在函数组件或者其他 hook 函数中;
    • 不能嵌套在 if/for/ 其它函数中(react 按照 hooks 的调用顺序识别每一个 hook )

    useEffect

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

    什么是副作用

    副作用是相对于主作用来说的,一个函数除了主作用,其他的作用就是副作用。对于 React 组件来说,主作用就是根据数据(state/props)渲染 UI,除此之外都是副作用(比如,手动修改 DOM)

    常见的副作用

    1. 数据请求 ajax 发送
    2. 手动修改 dom
    3. localstorage 操作

    使用步骤

    1. 导入 useEffect 函数
    2. 调用 useEffect 函数,并传入回调函数
    3. 在回调函数中编写副作用处理(dom操作)
    4. 修改数据状态
    5. 检测副作用是否生效

    代码实现

    1. import { useEffect, useState } from 'react'
    2. function App() {
    3. const [count, setCount] = useState(0)
    4. useEffect(()=>{
    5. // dom操作
    6. document.title = `当前已点击了${count}次`
    7. })
    8. return (
    9. <button onClick={() => { setCount(count + 1) }}>{count}button>
    10. )
    11. }
    12. export default App

    useEffect()依赖项控制执行时机

    1. 不添加依赖项

    组件首次渲染执行一次,以及不管是哪个状态更改引起组件更新时都会重新执行

    1. 组件初始渲染
    2. 组件更新 (不管是哪个状态引起的更新)
    1. // 默认无依赖项的写法:
    2. useEffect(() => {
    3. document.title = count
    4. }) // <--注意这里

    2. 添加空数组

    组件只在首次渲染时执行一次

    1. // 空数组依赖项的写法:函数体中不能使用状态
    2. useEffect(() => {
    3. document.title = 1
    4. }, []) // <--注意这里

    3. 添加特定依赖项

    副作用函数在首次渲染时执行,在依赖项发生变化时重新执行(多个依赖项时为“或”关系)

    1. // 依赖特定项的写法:
    2. useEffect(() => {
    3. document.title = count
    4. }, [count]) // <--注意这里,如果数组中有多个值,则任一值发生变化均会触发此函数执行

    注意事项

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

    清理副作用

    如果想要清理副作用 可以在副作用函数中的末尾 return 一个新的函数,在新的函数中编写清理副作用的逻辑

    注意执行时机为:

    1. 组件卸载时自动执行
    2. 组件更新时,下一个useEffect副作用函数执行之前自动执行
    1. const App = () => {
    2. const [count, setCount] = useState(0)
    3. useEffect(() => {
    4. const timerId = setInterval(() => {
    5. setCount(count + 1)
    6. }, 1000)
    7. return () => {
    8. // 用来清理副作用的事情
    9. clearInterval(timerId)
    10. }
    11. }, [count])
    12. return (
    13. <div>
    14. {count}
    15. div>
    16. )
    17. }

    注:如果使用 useEffect() 发送网络请求,并且使用 async/await 时,不可以直接在 useEffect 的回调函数外层直接包裹 async ,因为异步会导致函数无法立即返回,正确写法应该在内部单独定义一个函数,然后把这个函数包装成同步。示例如下:

    1. useEffect(()=>{
    2. // 注意:要在内部再定义一个函数才可以使用 async/await 修饰
    3. async function fetchData(){
    4. const res = await axios.get('http:/XXX.net/api/getData')
    5. console.log(res)
    6. }
    7. },[])

    useRef

    用于在函数组件中获取真实的dom元素对象或者是组件对象

    使用步骤

    1. 导入 useRef 函数
    2. 执行 useRef 函数并传入null,返回值为一个对象 内部有一个 current 属性存放拿到的dom对象(组件实例)
    3. 通过 ref 绑定 要获取的元素或者组件

    代码实现

    1. import React, { useEffect, useRef } from 'react'
    2. // useRef 的使用:函数组件由于没有实例,不能使用ref获取,如果想获取组件实例,必须是类组件
    3. class Test extends React.Component {
    4. render () {
    5. return (
    6. <div>这是Test组件div>
    7. )
    8. }
    9. }
    10. function App () {
    11. const testRef = useRef(null)
    12. const h1Ref = useRef(null)
    13. useEffect(() => {
    14. // 这里拿到的是组件示例所以可以直接访问组件内部的状态、方法
    15. console.log(testRef.current)
    16. console.log(h1Ref.current)
    17. // 注:useEffect 的回调是在 DOM 渲染完成后执行的,所以能拿到 DOM 元素
    18. })
    19. return (
    20. <div className="App">
    21. <Test ref={testRef} />
    22. <h1 ref={h1Ref}>Apph1>
    23. div>
    24. )
    25. }
    26. export default App

    useContext

    实现步骤

    1. 使用 createContext 创建 Context 对象
    2. 在顶层组件通过 Provider 提供数据
    3. 在底层组件通过 useContext 函数获取数据

    代码实现

    1. import React, { useState, createContext, useContext } from 'react'
    2. const Context = createContext()
    3. // 子组件
    4. function ComA () {
    5. // 获取上层组件传递的数据
    6. const count = useContext(Context)
    7. return (
    8. <div style={{ border: '1px solid red' }}>这里是ComA组件,count: {count}
    9. <br />
    10. <ComC />
    11. div>
    12. )
    13. }
    14. // 孙组件
    15. function ComC () {
    16. // 获取上层组件传递的数据
    17. const count = useContext(Context)
    18. return (
    19. <div style={{ backgroundColor: 'skyblue' }}>这里是ComC组件,count: {count}div>
    20. )
    21. }
    22. function App () {
    23. const [count, setCount] = useState(20)
    24. return (
    25. // 提供数据,固定写法,使用 Provider 节点包裹,然后使用 vaule 传值
    26. <Context.Provider value={count}>
    27. <div className="App">
    28. 这里是App组件,count: {count}
    29. <ComA />
    30. {/* 在父组件中修改了 count 子孙组件中使用的 count 也会同步更新 */}
    31. <p><button onClick={() => setCount(count + 1)}>count+1button>p>
    32. div>
    33. Context.Provider>
    34. )
    35. }
    36. export default App

    更多 hooks 详细知识-官网直达

  • 相关阅读:
    拥抱 Spring 全新 OAuth 解决方案
    Oracle数据库开发者工具
    如何将html转化为pdf
    Linux篇:进程
    算法Day16 | 104.二叉树的最大深度,559.n叉树的最大深度, 111.二叉树的最小深度,222.完全二叉树的节点个数
    凯百斯纳米盛装亮相2024济南生物发酵展专注于高压均质解决方案
    中国人民大学与加拿大女王大学金融硕士——在金融领域里持续探索、成长
    3DGS语义分割之LangSplat
    最长偶串的长度
    node.js 快速入门
  • 原文地址:https://blog.csdn.net/qq_43551801/article/details/126513135