11-09-react hook

习旻
2023-12-01

阮一峰链接

阮一峰链接

hook

使用hook的原因:
使用class创建组件,大型组件状态和逻辑组合在一起来,很难拆分和维护,使用不方便,所以改用hook。

hook作用:
在不使用class的情况下,也可以使用状态,也可以使用生命周期。使用函数创建数组。react hook就是加强版的函数式组件,完全可以不使用class,创建出一个复杂的组件。

hook钩子
react hook中提供很多的钩子,它的钩命名,都是use打头。

  • useState();
  • useEffect(); // 生命周期
  • useContext();
  • useReducer();
  • useCallback();

hook使用规则

只在最顶层使用 Hook
只在 React 函数中调用 Hook

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

export default ()=>{
    let [count,setCount] = useState(0);

    // 表示在函数内部顶层使用hook
    useEffect(()=>{
        if(count<=10){
            document.title=`点击了${count}次`;
        }
    })

    // 下面就不是在函数内部顶层使用hook,用法错误
    /*if(count<=10){
        useEffect(()=>{
            document.title=`点击了${count}次`;
        })
    }*/

    return(
        <div>
            <p>点击了{count}次</p>
            <button onClick={ e=>setCount(count+1) }>加1</button>
        </div>
    )
}

hook使用代码解析

useState()

import React,{ useState } from "react"
export default ()=>{
    // 使用钩子,数组前面的是状态,后面都是修改状态的函数。
    let [age,setAge] = useState(0);
    let [name,setName] = useState("wangcai")
    return(
        <div>
            <h2>我叫:{name},今年:{age}岁了</h2>
            <button onClick={()=>{setAge(age+100 ); setName("xiaoqiang")}}>小小按钮</button>
        </div>
    )
}

useEffect()

useEffect 相当于类中的三个钩子函数:

  • componentDidMount 挂载
  • componentDidUpdate 更新
  • componentWillUnmount 卸载

useEffect的参数

  • 如果useEffect只写一个参数,功能类似于 componentDidMount componentDidUpdate
  • useEffect还可以有第二个参数,如果第二个参数是[],表示执行componentDidMount
  • useEffect的第二个参数 [状态] 表示只有状态发生了改变,才会执行componentDidUpdate
// 下面的代码就类似于componentDidMount  componentDidUpdate
useEffect(()=>{
    document.title = `点击了${count}次`
})

// 下面的代码就类似于componentDidMount
useEffect(()=>{
    document.title = `点击了${count}次`
},[])

// 当count发生了改变,那么就会执行componentDidUpdate,这样写DidMount也执行了
useEffect(()=>{
    console.log("哈哈~")
    document.title = `点击了${count}次`
},[count])

componentWillUnmount

import React,{useState,useEffect} from "react"
import ReactDOM from "react-dom"
export default ()=>{
    let [count,setCount] = useState(0)

    // 当一个组件将要卸载,它会调用一个钩子,叫componentWillUnmount

    useEffect(()=>{
        document.title = `点击了${count}次`

        // return一个函数   return这个函数,就类似于componentWillUnmount
        return ()=>{
            // 此函数就类似于componentWillUnmount   一般在这里面做一个清理工作
            console.log("组件将要卸载,你看一下,你的定时器清除了吗?")
        }
    },[]); // 加上[]相当于不会执行xxxDidUpdate

    return(
        <div>
            <h2>点击了{count}次</h2>
            <button onClick={()=>setCount(count+1)}>加1</button>
            <button onClick={()=>ReactDOM.unmountComponentAtNode(document.getElementById("root"))}>杀死计算器</button>
        </div>
    )
}

useCallback

useCallback callback是回调的意思

语法:useCallback(()=>{ dosomting() },[])
useCallback可以指定第2个参数
第一个参数第1次会执行,之后它会根据第2个参数的变化决定是否要执行

useCallback(()=>{
    // 更新状态机
    setWeight(weight+1)
},[age])

第1次回调函数执行,后面这个回调函数执行与否,取决于age这个状态是否变化,如果age状态变化,就执行,如果不变化就不执行

function Demo() {
    let [age,setAge] = useState(1)
    let [weight,setWeight] = useState(50)

    function clickHeadle() {
        setAge(age+1)
    }

    return(
        <div>
            <p>年龄:{age}岁</p>
            <button onClick={clickHeadle}>年龄加1</button>
            <p>体重:{weight}岁</p>
            {/*<button onClick={()=>setWeight(weight+1)}>体重加1</button>*/}
            <button onClick={
                useCallback(()=>{
                    // 更新状态机
                    setWeight(weight+1)
                },[age])
            }>体重加1</button>
        </div>
    )
}

useReducer

useReducers()钩子用来引入 Reducer 功能。

import React,{ useReducer } from "react";

// useReducer
let initState = {
    count:0
}

function reducer(state,action) {
    switch (action.type) {
        case "increment":
            /*let newState = JSON.parse(JSON.stringify(state))
            newState.count = newState.count + 1;
            return newState;*/
            return {count:state.count+1}
        case "decrement":
            return {count:state.count-1}
        default:
            return state;
    }
}

function Demo13() {
    let [state,dispatch] = useReducer(reducer,initState)
    return(
        <div>
            计数器:{state.count}
            <div>
                <button onClick={()=>dispatch({ type:"increment" })}>+</button>
                <button onClick={()=>dispatch({ type:"decrement" })}>-</button>
            </div>
        </div>
    )
}

export default Demo13;

useContext

如果需要在组件之间共享状态,可以使用useContext()。

阮一峰链接

 类似资料: