其他分享
首页 > 其他分享> > React-Hook(3):useContext、useReducer、useRef、useMemo、useCallback

React-Hook(3):useContext、useReducer、useRef、useMemo、useCallback

作者:互联网

文章目录


一、useContext

一个react项目可以通过props传递参数,但props无法跨层级传递,而context却可以,他存储所有状态,每一个组件想要获取状态都可以直接向context请求状态和处理逻辑。对于钩子useContext,就有类似的功能。
代码:

function Demo() {
  var count=useContext(countContext)
  return(
    <div>
      <p>{count}</p>
    </div>
  )
}
//创建context
var countContext=React.createContext()

function App(){
  var [count,setCount]=useState(0)
  return(
    <div>
      <countContext.Provider value={count}>
        <Demo></Demo>
      </countContext.Provider>
      <button onClick={()=>{setCount(++count)}}>Add</button>
    </div>
  )
}

App组件中对于useContext写法固定。我们创建了一个countContext,传递状态count,所以Demo组件想要获取状态的时候可以直接从countContext中获取。var count=useContext(countContext)

二、useReducer

之前在redux中接触过reducer,是存储改变状态的逻辑的,所以我们先定义一个reducer,然后使用useReducer。
useReducer的两个参数,第一个是我们定义的reducer,另一个是状态初始值。代买如下:

function reducer(state,action){
  switch(action.type){
    case "Add":{

    }
    default:{
      return state
    }
  }
}

function App(){
  var [count,setCount]=useState(0)
  console.log(useReducer(reducer,{num:0}))
  return(
    <div>
      <countContext.Provider value={count}>
        <Demo></Demo>
      </countContext.Provider>
      <button onClick={()=>{setCount(++count)}}>Add</button>
    </div>
  )
}

打印结果如下:
在这里插入图片描述
可以发现,这是一个含有初始值和改变逻辑函数的对象。其中的fun就相当于我们学过的dispatch。
代码如下:


function reducer(state,action){
  switch(action.type){
    case "Add":{
       return{
         num:state.num++
       }
    }
    default:{
      return state
    }
  }
}
function App(){
  console.log(useReducer(reducer,{num:0}))
  var [state,dispatch]=useReducer(reducer,{num:0})
  return(
    <div>

      <h1>{state.num}</h1>
      <button onClick={()=>{dispatch({type:"Add"})}}>changeNum</button>
    </div>
  )
}

由此也可以发现useState和useReducer的不同之处,两者开始的使用方法似乎相似,但返回的结果却有不同,维护的改变状态的方法种类数量也不同。

三、useRef

获取input标签下的值。先引入,创建useRef这个钩子,最后获取结果
代码如下:

function App(){
  var useRefInput=useRef()
  console.log(useRefInput.current)
  return(
    <div>
      <input ref={useRefInput} type="text"></input>
    </div>
  )
}

结果输出:
在这里插入图片描述

四、useMemo

对于App内部定义的函数,正常来讲,谁调用谁就会触发其逻辑,但是出现了如下情况:
代码:


function App(){
  var [count,setCount]=useState(0)
  var [value,setValue]=useState(0)
  var a=function(){
    console.log("11111")
    return count
  }
  return (
      <div>
        <p>{a()}</p>
        <p>{value}</p>
        <button onClick={()=>{setCount(++count)}}>Count</button>
        <button onClick={()=>{setValue(++value)}}>Value</button>
      </div>
  )
}

如上代码,应该只有在点击Count时才会输出“11111",但是运行时我们发现,点击Value时也会触发打印:
在这里插入图片描述
而Hook useMemo就可以很好解决这个问题。useMemo传入函数a,代码如下:

function App(){
  var [count,setCount]=useState(0)
  var [value,setValue]=useState(0)
  var a=useMemo(function(){
    console.log("11111")
    return count
  })
  console.log(a)
  return (
      <div>
        {/* <p>{a()}</p> */}
        <p>{value}</p>
        <button onClick={()=>{setCount(++count)}}>Count</button>
        <button onClick={()=>{setValue(++value)}}>Value</button>
      </div>
  )
}

打印输出
在这里插入图片描述
这也就说明使用useMemo之后返回的直接就是我们return的值0,然后还要传入我们函数的依赖项,最后代码:

function App(){
  var [count,setCount]=useState(0)
  var [value,setValue]=useState(0)
  var a=useMemo(function(){
    console.log("11111")
    return count
  },[count])
  // console.log(a)
  return (
      <div>
        <p>{a}</p>
        <p>{value}</p>
        <button onClick={()=>{setCount(++count)}}>Count</button>
        <button onClick={()=>{setValue(++value)}}>Value</button>
      </div>
  )
}

结果如下(点击Value不会再触发a函数了):
在这里插入图片描述

五、useCallback

useCallback和useMemo的用法差不多,它也需要写入依赖项,而内部的返回值只有在依赖项发生变化时,才会返回,如下代码:

function App(){
  var [count,setCount]=useState(0)
  var [value,setValue]=useState(0)
  var a=useCallback(function(){
    console.log("11111")
    return count
  },[value])
  console.log(a)
  return (
      <div>
        {/* <p>{a()}</p> */}
        <p>{value}</p>
        <button onClick={()=>{setCount(++count)}}>Count</button>
        <button onClick={()=>{setValue(++value)}}>Value</button>
      </div>
  )
}

结果可以看出,它返回的不是return的值,而是a函数,所以调用时要用a()
在这里插入图片描述
然后调用
开始时,发现我们点击Count了8次只加了1(异步):
在这里插入图片描述

但当我们点击一下Value时,Count的8下同步到视图中,Value+1:
在这里插入图片描述
从这里我们可以看出useCallback是只有在依赖项发生变化时,函数才会返回一个新的返回值(count也在增加,只是不返回新的返回值)

标签:count,function,useRef,return,useMemo,useReducer,value,setCount,var
来源: https://blog.csdn.net/qq_45856669/article/details/123306134