一、useState
二、 useEffect
三、 useCallback
四、 useMemo
五、 useContext
含义:useContex用于在组件中获取上层组件通过 Context 提供的数据。它可以让你跨越组件树层级来访问共享的数据,避免了通过层层传递 props 的带来的问题。
1.实现数据的跨级传递(父组件的数据可以直接传递给孙组件或者孙孙组件)
2.组件本身可以充当数据的消费者和数据的提供者
3.若要在子组件中使用父组件的过程中,修改了子组件中的数据后,父组件中使用了该变量的地方都会刷新,则在使用provider和value进行传值时,可以以数组的形式进行传递,这样子组件即可正常使用set来修改数据了(同步更新)
<Sonctx.Provider value={[sonmsg, setsonmsg]}>
                <Grandson></Grandson>
            </Sonctx.Provider> 
//app上下文对象==================================================
// 1-1:=======创建appctx文件并编辑下面语句
import React from "react";
// 创建一个上下文对象
let Appctx = React.createContext({})
// 导出appctx对象
export default Appctx
//子组件的上下文对象==========================================================
import React from "react";
// 创建一个上下文对象
let Sonctx = React.createContext({})
// 导出Sonctx对象
export default Sonctx
//孙组件上下文对象==========================================================
import React from "react";
// 创建一个上下文对象
let GrandsonCtx = React.createContext({})
// 导出GrandsonCtx对象
export default GrandsonCtx
//app组件中=============================================================
import React, { useState, useCallback } from 'react'
import Son from './component/hook/01-Son.jsx'
//1-2======== 引入自己创建的Appctx上下文对象
import Appctx from './component/hook/01-app.jsx'
function App() {
  // 定义一个appmsg数据
  let [appmsg, setmsg] = useState({ name: "jack", age: 23 })
  return (
    <div>
      <h5>app组件</h5>
      <div>{appmsg.name}</div>
      {/* 1-3=======:使用provider标签和value属性来传递 父组件的appmsg数据*/}
      <Appctx.Provider value={appmsg}>
        <Son></Son>
      </Appctx.Provider>
    </div>
  )
}
export default App
//son组件中===================================================================================
import React, { useContext, useState } from 'react'
import Grandson from './02-granSon.jsx'
//1-5======: 引入appctx上下文对象
import Appctx from './01-app.jsx'
// 2-1:引入Sonctx这个上下文对象,是自己创建的
import Sonctx from './01-Sonctx.jsx'
function Son() {
    // 1-6======:引入useContext这个函数,用useContext来接收从父组件传递过来的数据进行解构赋值
    let obj = useContext(Appctx)
    console.log("son组件的obj222", obj);
    //2-2: son组件可以是消费者,也可以作为别人的数据提供者:定义一个变量sonmsg
    const [sonmsg, setsonmsg] = useState({ name: "小将", age: 26, sex: "girl" })
    return (
        <div>
            <h5>son组件</h5>
            {/* 这里即可正常使用父组件传递过来的数据 */}
            <div>{obj.name}</div>
            <div>{obj.age}</div>
            <div>son组件的值==当孙组件进行修改了sge数据,这里是否会改变======{sonmsg.age}</div>
            {/* 使用provider标签和value属性进行传递 */}
            {/*2-3: son组件给grandson组件提供数据 */}
            {/* 这里将son的数据sonmsg和setsonmsg传递给了孙组件,即可实现在孙组件中修改子组件的值了 */}
            <Sonctx.Provider value={[sonmsg, setsonmsg]}>
                <Grandson></Grandson>
            </Sonctx.Provider>
        </div>
    )
}
export default Son
//孙组件中================================================================
import React, { useContext } from 'react'
import Appctx from './01-app'
// 2-4====引入Sonctx这个上下文对象
import Sonctx from './01-Sonctx'
function Grandson() {
    // 2-5===使用usecontext来接收从son组件中传递过来的数据进行解构赋值
    let [granobj, setsonmsg] = useContext(Sonctx)
    console.log("grandson的数据::孙组件", granobj, 1111, setsonmsg);
    // 父组件可以直接将其数据传递给孙组件乃至孙孙组件
    let Apobj = useContext(Appctx)
    console.log("app传递过来的数据", Apobj);
    let change = () => {
        // 这是主流的写法,19行为深拷贝的概念,这不是标准的写法
        granobj.age = "33"
        setsonmsg(JSON.parse(JSON.stringify(granobj)))
    }
    return (
        <div>
            <h5>Grandson组件</h5>
            {/* 2-6===即可将其看作变量正常使用 */}
            <div>{granobj.name}</div>
            <div>{granobj.age}</div>
            <div>{granobj.sex}</div>
            <button onClick={change}>孙按钮</button>
        </div>
    )
}
export default Grandson
 
 
 
六、useReduce
含义:和useState类似,都是用来管理组件状态的,只是useReducer返回的dispatch函数是用来改变state的action值得,而不是直接设置state的值,不同的action如何产生新的state的值是在reducer函数里面定义的。
格式:const [state,dispatch]=usereducer(reducer,initialArg,init?)
state:当前的变量
dispatch:用于修改state的函数,类似于usestate中的set函数
reducer:一个函数,格式为:let reducer=(currentState,action)=>newState,该函数会接收当前的state和当前的dispatch中的action为参数,然后返回一个state,也就是说,reducer函数负责状态转换的工作。(可以决定如何修改state这个变量)
通过当前的状态(state)和动作(action)返回修改后的新的状态的值,接收两个参数:状态值(state)和状态值(action)
initialArg:state的初始值
init:把第二个参数传给了第三个函数,让这个函数处理一下,处理的结果作为初始值传递给state
import React, { useReducer } from 'react'
function App() {
  let [count, setcount] = useReducer((currentstate, action) => {
    console.log(currentstate, action);
    // count的值是return返回的值,返回为20的话,点击按钮,页面的变量为20咯,再一次点击:当前的值也就是return返回的值20,页面也就不会再刷新了
    return 20
    // 返回为action的话,传递的是最新的值,点击按钮,页面便是修改后的值:1,6,11。。。。。。。。
    // return action
    //若有第三个参数存在的话就是将第二个参数处理一下,然后将处理过的数据给state作为初始值:这里是将1交给第三个参数将其加100后给count。最后页面一加载,页面显示的是101
  }, 1, (arg) => { return arg + 100 })
  let change = () => {
    setcount(count + 5)
  }
  return (
    <div>
      <h5>app组件</h5>
      <div>{count}</div>
      <button onClick={change}>{count}</button>
    </div>
  )
}
export default App 
进阶版
若该变量里面的数据比较多,对其进行修改和传递的写法
问::1.switch里面的case语句都是相似的,但为什么不直接使用下面这个写法呢
                ![]()
上面的写法是处理好了再将处理好了再传递过去修改
下面的写法:在case里面可以写业务逻辑的,可以自己决定如何处理该数据,也就是统一来配置修改仓库的逻辑
case语句里面的修改是统一修改的逻辑代码。
2.case语句里的为什么要大写呢?
答:为了和普通的数据进行区分,不是数据,是取数据和保存数据的一个判断。
import React, { useReducer } from 'react'
function App() {
  // 1.1====让count的初始值为obj这个对象
  let obj = { name: "cup杯子", price: "14", comment: "非常好呀,下次还来" }
  // 1.2解构赋值====这里的dispatch相当于usestate的set函数
  let [count, dispatch] = useReducer(reducer, obj)
  // 1.3=========定义reducer函数:currentstate:为当前的那个状态,action传进来的最新的那个
  let reducer = (currentstate, action) => {
    console.log("当前的那个状态:", currentstate, "传进来的那个状态:", action);
    // 1.5==== 用switch进行判断,匹配是否匹配
    switch (action.type) {
      case "NAME":
        // 1.6===将新值传递给旧值:currentstate为旧值,action为新值
        currentstate.name = action.value
        break;
      case "PRICE":
        currentstate.price = action.value
        break;
      case "COMMENT":
        currentstate.comment = action.value
        break;
    }
    //1.7===== currentstate确实被修改了,但它本身是一个引用数据,属性值改变了,但属性没改,返回的还是引用数据所以页面不会刷新,需要用到深拷贝的知识点
    return JSON.parse(JSON.stringify(currentstate))
  }
  // 1.4====:通过dispatch中的type和value来实现数据修改
  let change = () => {
    dispatch({ type: "PRICE", value: "20" })
  }
  return (
    <div>
      <h5>app组件</h5>
      <div>{count.name}</div>
      <div>{count.price}</div>
      <button onClick={change}>{count.price + 10}</button>
    </div>
  )
}
export default App 
进阶版,将reducer函数封装到一个文件中,直接引进来使用。
将reducer封装到一个文件中,引入使用=========================================================
import { useReducer } from "react";
function usestore() {
    // 1.1====让count的初始值为obj这个对象
    let obj = { name: "cup杯子", price: "14", comment: "非常好呀,下次还来" }
    // 1.3=========定义reducer函数:currentstate:为当前的那个状态,action传进来的最新的那个
    let reducer = (currentstate, action) => {
        console.log("当前的那个状态:", currentstate, "传进来的那个状态:", action);
        // 1.5==== 用switch进行判断,匹配是否匹配
        switch (action.type) {
            case "NAME":
                // 1.6===将新值传递给旧值:currentstate为旧值,action为新值
                currentstate.name = action.value
                break;
            case "PRICE":
                currentstate.price = action.value
                break;
            case "COMMENT":
                currentstate.comment = action.value
                break;
        }
        //1.7===== currentstate确实被修改了,但它本身是一个引用数据,属性值改变了,但属性没改,返回的还是引用数据所以页面不会刷新,需要用到深拷贝的知识点
        return JSON.parse(JSON.stringify(currentstate))
    }
    // 解构赋值:将store的初始值赋值为obj这个对象
    let [store, dispatch] = useReducer(reducer, obj)
    return [store, dispatch]
}
// 导出的是自己自定义的hook
export default usestore
app组件中===================================================
import React, { useReducer } from 'react'
import Son from './component/01-son.jsx'
// 引入自己定义的storehook
import usestore from './store.jsx'
function App() {
  // 使用自定义的
  let [store, dispatch] = usestore()
  console.log(store);
  // 使用action将name的值改为海绵宝宝好杯子
  let action = { type: "NAME", value: "海绵宝宝好杯子" }
  // 点击按钮,则调用dispatch函数,
  let change = () => {
    dispatch(action)
  }
  // 现在存在一个问:app组件和son组件中都有name属性,在son组件中点击按钮将name的值改变了,son页面的值改变了,但app组件没有改变
  // 因为引进来的是一个函数,每一次调用的都是独立的结果,各各自是各自的。
  return (
    <div>
      <h5>app组件</h5>
      <div>{store.name}</div>
      <div>{store.price}</div>
      <Son></Son>
    </div>
  )
}
export default App
//son组件中===========================================================================
import React, { useReducer } from 'react'
// 引入自己定义的storehook
import usestore from '../store.jsx'
function Son() {
    let [store, dispatch] = usestore()
    console.log(store);
    // 使用action将name的值改为海绵宝宝好杯子
    let action = { type: "NAME", value: "海绵宝宝好杯子" }
    // 点击按钮,则调用dispatch函数,
    let change = () => {
        dispatch(action)
    }
    return (
        <div>
            <h5>son组件</h5>
            <div>{store.name}</div>
            <button onClick={change}>{store.name}</button>
        </div>
    )
}
export default Son
 
 问题:app组件和son组件中都有name属性,在son组件中点击按钮将name的值改变了,son页面的值改变了,但app组件没有改变。
           因为引进来的是一个函数,每一次调用的都是独立的结果,各各自是各自的。
所以要利用usecontext、插槽、usereducer来实现仓库
在main.jsx文件中引入刚刚封装的store
七、useRef
八、自定义Hoook
含义:将官方的hooks搭配使用设计出自己的use开头的函数,该函数具备自定义的功能,就是自定义hook。
九、高阶组件
含义:函数调用后返回了一个组件,这个函数就是高阶组件








![[C/C++]数据结构 链表OJ题 : 链表中倒数第k个结点](https://img-blog.csdnimg.cn/aa67e8afba5c4036891a0dc39cbd2090.png)










![CNVD-2023-08743:宏景HCM SQL注入漏洞复现 [附POC]](https://img-blog.csdnimg.cn/8b95f8617da244c28eaf7e2dd8f92369.png)