react hooks

127 阅读3分钟

实现函数组件,代替类组件。

  1. 解决calss的复杂(this指向,生命周期等)
  2. 解决业务逻辑复杂,难以拆分
  3. 状态逻辑变得简单
  4. 函数组件的思想更加符合react的设计理念

注: 约定钩子一律使用use前缀,自定义也要如此

useState 状态钩子

纯函数组件没有状态,该钩子为函数组件引入state,并进行数据操作

import { useState, FC } from 'react'
//FC  函数式组件的一个 ts泛型
const Index: FC = () => {
    //useState(0) 传参 ,设置初始值
    // count: 状态数据   setCount:设置状态数据
    const [count, setCount] = useState(0)

    function addCount() {
        // 参数非函数值,直接指定新的状态,覆盖原来的状态值
        setCount(count + 1)
        //函数式组件 接受新的状态,返回新的状态
        // setCount((value) => newValue)
    }
    return (
        <>
            <div>{count}</div>
            <button onClick={addCount}>点击一下</button>
        </>
    )
}

export default Index

useContext 共享状态钩子

状态分发,避免逐层props传递数据

context: 父组件与其内部组件(所有后代组件)数据共享

import { useState, FC, useContext, createContext } from 'react'
//定义Context 容器对象
const CountContext = createContext(0)
//FC  函数式组件的一个 ts泛型
const Index: FC = () => {
    const [count, setCount] = useState(0)

    function addCount() {
        setCount(count + 1)
    }
    return (
        <>
            <div>{count}</div>
            <button onClick={addCount}>点击一下</button>
            {/* 通过value传值  外面要包裹 xxxContext.Provider*/}
            <CountContext.Provider value={count}>
                <Child />
            </CountContext.Provider>
        </>
    )
}
const Child = () => {
    // 获取数据
    const count = useContext(CountContext)
    return <div>子组件{count}</div>
}

export default Index

useEffect 副作用钩子 (异步执行)

用于在函数组件中进行 接口请求,订阅,监听等操作。模拟类组件中的生命周期(可以看做,componentDidMount,componentDidUpdate,componentWillUnmount三个函数的组合)。

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

//FC  函数式组件的一个 ts泛型
const Index: FC = () => {
    const [count, setCount] = useState(0)

    function addCount() {
        setCount(count + 1)
    }
    
    // 接受两个参数,1: 异步操作函数  2:参数是一个数组
    
    // 第二个参数为空 每次渲染都会执行  类似
    // useEffect(() => {
    //     //操作
    //     console.log(count)
    //     return () => {
    //         // 卸载之后执行
    //     }
    // })
    
    // 第二个参数为空数组  组件挂载后,运行一下
    // useEffect(() => {
    //     //操作
    //     console.log(count)
    //     return () => {
    //         // 卸载之后执行
    //     }
    // },[])
    
    // 第二个参数 有参数 ,监听参数的改变
    // useEffect(() => {
    //     //操作
    //     console.log(count)
    //     return () => {
    //         // 卸载之后执行
    //     }
    // }, [count])

    return (
        <>
            <div>{count}</div>
            <button onClick={addCount}>点击一下</button>
        </>
    )
}

export default Index

useReducer Action钩子

在某种情况下可取代 redux

import { FC, useReducer } from 'react'

const reduce = (state, action) => {
    if (action.flage === 'add') {
        return {
            ...state,
            count: state.count + 1
        }
    } else {
        return {
            ...state,
            count: state.count - 1
        }
    }
}
const initState = {
    count: 0
}
//FC  函数式组件的一个 ts泛型
const Index: FC = () => {
    // 可接受三个参数  参1:reduce函数,  参2: 初始化参数,参3:初始化函数
    //有第三个参数  ,为惰性初始化


    // 正常使用
    const [state, dispatch] = useReducer(reduce, initState)

    function addCount() {
        dispatch({
            flage: 'add'
        })
    }
    function disCount() {
        dispatch({
            flage: 'subtract'
        })
    }

    return (
        <>
            <div>{state.count}</div>
            <button onClick={addCount}>点击一下</button>
            <button onClick={disCount}>点击一下</button>
        </>
    )
}

export default Index

useRef 获取Dom节点

为Dom 节点创建持久引用,有一个current 属性,可访问引用的节点,和react.createRef()功能相似

import { FC, useRef } from 'react'

//FC  函数式组件的一个 ts泛型
const Index: FC = () => {
    const refInput: any = useRef()
    function getInput() {
        console.log(refInput?.current?.value)
    }
    return (
        <>
            <input ref={refInput} />
            <button onClick={getInput}>获取input值</button>
        </>
    )
}

export default Index

useMemo 缓存计算结果

在后续的渲染中,只要依赖得数组不发生变化,就直接使用缓存结果,提供组件的渲染性能

import { FC, useMemo } from 'react'

//FC  函数式组件的一个 ts泛型
const Index: FC = () => {
    const data1 = 1
    const data2 = 2

  // 接受两个参数  参1:函数,返回值作为缓存值 。参2:依赖数组
  //依赖数组中的值发生变化,重新计算。否则直接取上次计算数据
    const result = useMemo(() => {
        return data1 + data2
    }, [data1, data2])

    return (
        <>
            <button>{result}</button>
        </>
    )
}

export default Index

useCallback 渲染性能优化 (缓存函数本身)

import { FC, useCallback } from 'react'

//FC  函数式组件的一个 ts泛型
const Index: FC = () => {
    const data1 = 1
    const data2 = 2

    // 接受两个参数  参1:函数,返回值作为缓存值 。参2:依赖数组
    //依赖数组中的值发生变化,重新计算。否则直接取上次计算数据
    
    // 如果没有传入依赖数组,记忆函数每次都会更新
    const result = useCallback(() => {
        return data1 + data2
    }, [data1, data2])

    return (
        <>
            <button>{result()}</button>
        </>
    )
}

export default Index

useLayoutEffect 副作用钩子 所有的dom变更之后,同步执行

同useEffect

useImperativeHandle 把ref 自定义暴露给父组件

用于父组件控制子组件dom