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