React Hooks

82 阅读3分钟

React Hooks

useState(函数式编程)
// 使用useState来创建状态
// 1. 引入
import React, { useState } from 'react'
function StateFun () {
    // 2. 接收一个参数做为初始值 
    const [name, setName] = useState('111') 
    // 3. 返回一个数组 第一个值为状态 第二个为改变状态的值
    return <div onClick={() => { setName('222') }}>函数组件{name}</div>
    
    // setName修改值时它是同步还是异步? 
    // setName 是异步更新

    // 连续调用 setName 会发生什么? 
    // 传入的是一个普通值,他只会进行最后一次更新   
    // 传入一个函数的话,它会进行两次赋值,因为它更新的值是基于之前的值来执行,所以在开发中推荐使用函数传入的形式进行修改;
}
export default StateFun
useEffect(解决副作用)

执行时机在 rendar之后

// 1. 引入
import React, { useEffect, useState } from 'react'
function StateFun () {
    const [num, setNum] = useState(1)
    // 2. 接收一个函数作为参数
    // 3. 接收第二个参数 依赖列表 依赖更新时,才执行参数 空数组执行一次 无第二个参数时 全都执行
    // 4. 先执行返回函数 再执行参数函数
    useEffect(() => {
        console.log('2') // 参数函数
        return () => { 
            console.log('1') // 返回函数
        }
    })
    return <div onClick={() => { setNum(num => num + 1) }}>函数组件{num}</div>
}
export default StateFun
useLayoutEffect(监测DOM)

执行时机在 DOM更新之后

// 1. 引入
import React, { useEffect, useState } from 'react'
function StateFun () {
    const [num, setNum] = useState(1)
    // 2. 接收一个函数作为参数
    // 3. 接收第二个参数 依赖列表 依赖更新时,才执行参数 空数组执行一次 无第二个参数时 全都执行
    // 4. 先执行返回函数 再执行参数函数
    useLayoutEffect(() => {
        console.log('2') // 参数函数
        return () => { 
            console.log('1') // 返回函数
        }
    })
    return <div onClick={() => { setNum(num => num + 1) }}>函数组件{num}</div>
}
export default StateFun
useMemo(组件跟随状态更新)
// 1. 引入
import React, { useState, useMemo } from 'react'
function StateFun () {
    const [age, setAge] = useState(10)
    const [name, setName] = useState(1)
    // 2. 接收一个函数作为参数
    // 3. 接收第二个参数 依赖列表 依赖更新时,才执行参数 空数组执行一次 无第二个参数时 全都执行
    // 4. 返回的是一个值
    const ageDouble = useMemo(() => {
        return age * 2
    }, [age])
    return <div onClick={() => { setName(name => name + 1) }}>age:{age} name:{name} 双倍:{ageDouble}</div>
}
export default StateFun
useCallback(组件跟随状态更新)
// 1. 引入
import React, { useState, useCallback } from 'react'
function StateFun () {
    const [age, setAge] = useState(10)
    const [name, setName] = useState(1)
    // 2. useMemo useCallback 使用相同
    // 3. useMemo返回的是一个值 useCallback返回一个函数
    // 4. 不同点  useMemo缓存的是一个值 useCallback缓存一个函数
    const ageDouble = useCallback(() => {
        return age * 2
    }, [age])
    return <div onClick={() => { setAge(name => name + 1) }}>age:{age} name:{name} 双倍:{ageDouble()}</div>
}
export default StateFun
useRef(长久保存数据)

// 1. 引入
import React, { useState, useEffect, useRef } from 'react'
function StateFun () {
    const [num, setNum] = useState(1)
    const ref = useRef()
    // 返回的 ref 对象在组件的整个生命周期内保持不变 useRef 类似于类组件的 this
    // 修改 Ref 对象中current的值并不会引发组件的重新渲染
    useEffect(() => {
        ref.current = setInterval(() => {
            setNum(num => num + 1)
        }, 400)
        return () => {
            clearInterval(ref.current)
        }
    }, [])
    useEffect(() => {
        if (num > 10) {
            clearInterval(ref.current)
        }
    }, [num])
    return <div> num:{num}</div>
}
export default StateFun
useContext(组件之间共享状态)

import React, { useContext, createContext, useState } from 'react'
// 引入 useContext createContext
// 通过 createContext创建一个Context句柄
// Context.Provider来确定共享范围
// 通过value 分发内容
// 子组件通过useContext(Context句柄) 来获取数据
const Context = createContext()
function StateFun () {
    const [num, setNum] = useState(1)
    console.log('Context', Context)
    return <div>
        父组件:{num}
        <Context.Provider value={num}>
            <Item1></Item1>
            <Item2></Item2>
        </Context.Provider>
    </div>
}

function Item1 () {
    const num = useContext(Context)
    return <div>子组件1  num:{num}</div>
}
function Item2 () {
    const num = useContext(Context)
    return <div>子组件2 num:{num}</div>
}
export default StateFun
useReducer(复杂逻辑简单化)

import React, { useReducer } from 'react'
const store = {
    num: 10
}
// useReducer使用方法
// 创建 数据仓库(store) 和 管理者(reducer)
// 通过 useReducer(reducer, store)来获取state和dispatch
const reducer = (state, action) => {
    console.log('state', state)
    console.log('action', action)
    switch (action.type) {
        case 'setNum':
            return {
                ...state,
                num: action.num
            }
        default:
            return {
                ...state
            }
    }
}
function StateFun () {
    const [state, dispatch] = useReducer(reducer, store)
    return <div onClick={() => {
        dispatch({
            type: 'setNum',
            num: 100
        })
    }}>
        父组件:{state.num}
    </div>
}

export default StateFun