一文带你了解React Hooks

目录

一、useState

二、useRef

三、useEffect

四、自定义Hook

五、Hooks使用规则


Hooks原意是“挂钩”,指将类组件中的部分功能直接可以挂钩函数组件中,例如state、生命周期方法、副作用等功能。

为什么使用Hooks?

  1. 封装代码,提高复用性
  2. 更强的可读性

一、useState

概念

  • useState是React的一个Hook函数,它运行我们向组件添加一个状态变量,从而控制影响组件的渲染结果
  • 制作响应式数据

示例:useState 实现一个自增计数器

import {useState} from "react";

function App() {
    // 1. 调用useState添加一个状态变量
    // count:状态变量
    // setCount:修改状态变量的方法
    const [count, setCount] = useState(0);

    // 2. 点击事件回调
    const handleClick = () => {
        /**
         * 作用
         * 1. 用传入的新值修改count
         * 2. 重新使用新的count渲染UI
         */
        setCount(count + 1);
    }
    return (
        <div className="App">
            <button onClick={handleClick}>{count}</button>
        </div>
    );
}

export default App;

规则

  1. 状态不可变:状态被认为是只读的,我们应该始终替换它而不是修改它,直接修改不能引发视图更新
  • 个人理解:要修改状态变量,只能使用它提供的setXxx()方法,如果直接修改,该状态是不会联动视图一起修改的

  1. 修改状态对象:对于对象类型的状态变量,应该始终传给set方法一个全新的对象来进行修改
  • 个人理解:如果状态变量是对象,那么传给set方法的应该是一个全新的对象,而不是在原本的对象的基础上修改,然后再传给set方法


二、useRef

作用

  • 获取 / 操作DOM

步骤

  1. 使用useRef创建ref对象,并与JSX绑定
  2. 在DOM可用时,通过ref对象.current拿到DOM对象
  • 渲染完毕之后(dom生成之后)才可用
import {useRef} from "react";

function App() {
    // 1. 使用useRef创建ref对象,并与JSX绑定
    const inputRef = useRef(null)

    // 2. 在DOM可用时,通过ref对象.current拿到DOM对象
    const showDOM = () => {
        console.dir(inputRef.current)
    }
    return (
        <div>
            <input type="text" ref={inputRef}/>
            <button onClick={() => showDOM()}>showDOM</button>
        </div>
    );
}

export default App;

三、useEffect

作用

  • 用于在React组件中触发不是由事件引起而是由渲染本身引起的操作,比如发生AJAX请求、更改DOM等等
  • 个人理解:类似Vue组件的生命周期,我们可以在不同生命周期内做不同的事情

基础使用

useEffect(() => {}, [])

参数详解

  • 参数1:副作用函数,函数内部放置需要执行的操作
  • 参数2(可选):在数组里放置依赖性,不同的依赖项会影响副作用函数的执行
    • 空数组:副作用函数只会在组件渲染完毕后执行一次
import {useEffect, useState} from "react";


const URL = "http://geek.itheima.net/v1_0/channels"

function App() {

    // 频道列表
    const [list, setList] = useState([])
    useEffect(() => {
        async function getList() {
            const res = await fetch(URL)
            const channels = await res.json()
            setList(channels.data.channels)
        }
        getList()
    }, [])

    return (
        <div>
            this is app
            <ul>
                {list.map(item => (
                        <li key={item.id}>{item.name}</li>
                    )
                )}
            </ul>
        </div>
    );
}

export default App;

依赖项参数说明(执行时机

依赖项

副作用函数执行时机

  1. 组件初始渲染
  2. 组件更新时执行

空数组

只在初始渲染时执行一次

特定依赖项

  1. 组件初始渲染
  2. 特定依赖项变化时执行
import {useEffect, useState} from "react";

function App() {
    const [count, setCount] = useState(0)
    // 1. 没有依赖项:初始 + 组件更新
    // useEffect(() => {
    //     console.log("副作用函数执行了")
    // })

    // 2. 空数组:初始执行一次
    // useEffect(() => {
    //     console.log("副作用函数执行了")
    // }, [])

    // 3. 特定依赖项:初始 + 特定依赖性更新
    useEffect(() => {
        console.log("副作用函数执行了")
    }, [count])

    return (
        <div>
            this is app
            <button onClick={() => setCount(count + 1)}>{count}</button>
        </div>
    );
}

export default App;

清除副作用

副作用操作

  • 在useEffect中编写的由渲染本身引起的对接组件外部的操作
  • 比如:useEffect中开启了一个定时器,我们想在组件卸载时把这个定时器清理掉,这个过程就是清理副作用
useEffect(() => {
  // 实现副作用操作逻辑
  return () => {
    // 清除副作用逻辑
  }
}, [])

说明:清除副作用的函数最常见的执行时机是在组件卸载时自动执行

四、自定义Hook

概念

  • 自定义Hook是以use打头的函数,通过自定义Hook函数可以用来实现逻辑的封装和复用

示例:控制元素显示

import {useState} from "react";

// 封装自定义Hook
function useToggle() {
    const [value, setValue] = useState(true);
    const toggle = () => setValue(!value);

    return {
        value, toggle
    }
}

function App() {
    const {value, toggle} = useToggle();

    return (
        <div>
            {value && <div>this is app</div>}
            <button onClick={toggle}>toggle</button>
        </div>
    );
}

export default App;

五、Hooks使用规则

规则

1)只能在组件中或者其他自定义Hook函数中调用

2)只能在组件的顶层调用,不能嵌套在if、for、其他函数中

即函数的定义不能出现在上述情况中,但函数所产生的属性或方法可以

错误示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值