一、作用
我们知道react组件有两种写法一种是类组件,另一种是函数组件。而函数组件是无状态组件,如果我们要想改变组件中的状态就无法实现了。为此,在react16.8版本后官方推出hooks,用于函数组件更改状态。
二、常用API
1、useState:存储变量和修改变量
用法:
有两个参数,第一个参数:状态中的属性。第二个参数:更改第一个参数属性值的回调函数。
2、useeffect
给函数组件增加了操作副作用的能力,通俗说就是让你某方法在特定的时刻才会去执行,例如清除定时器
用法:
2-1、 两个参数。第一个参数:回调函数,第二个参数,是一个数组,里面存放执行回调函数的依赖,当为空数组时候,该回调函数在该组件中只会执行一次。
2-2、 如果在useEffect第一个回调函数后加了一个return,那么return里面相当于类组件中的组件销毁生命周期,在return里可以写一些组件销毁时候要做的一些业务逻辑。
2-3、 一个组件内可以写多个useEffect
2-4、和useLayoutEffect的区别
useLayoutEffect:在渲染页面前执行,会阻塞渲染。当要在渲染页面前操作dom时候应使用useLayoutEffect,否则用useEffect会出现页面抖动的情况。
useEffect:当组件页面渲染完,才会执行里面的逻辑。
3、useCallback(记忆函数)
当某个状态发生改变导致组件重新渲染时,为防止与该状态无关的其他函数重新被创建,使用useCallback方法
用法:
两个参数。第一个参数:被记忆的函数。第二个参数:是一个数组,里面放需要重新创建被记忆的函数的依赖。(例如。在点击修改name组件按钮重新渲染的时候,为了防止重新创建Add函数,我们可以给Add函数加useCallback,这样只有在第二个参数中num依赖发生改变的时候才会重新创建Add函数
4、useMemo (相当于vue中的计算属性)
两个参数。第一个参数:被记忆的函数。第二个参数:是一个数组,里面放需要重新计算的函数返回值的依赖。
useMemo 缓存的结果是回调函数中return回来的值,主要用于缓存计算结果的值,应用场景如需要计算的状态 useCallback 缓存的结果是函数,主要用于缓存函数
5、useRef 可以获取dom元素,还可以和useState一样存放变量。
6、useContext
可以帮助我们跨越组件层级直接传递变量,实现数据共享。
在react组件传值的博客中我们说到兄弟组件采用生产者和消费者。写起来很繁琐。
而使用hooks中useContext就很方便了,包裹组件的父组件代码基本没变化,主要消费者获取值很方便了,如下图
7、useReducer 管理各个组件公共状态 一般与useContext结合使用
用法:
该方法接受两个参数。第一个参数:reducer,第二个参数:默认state,通过解构获取useReducer中的state和dispatch。
完整代码如下:
import React,{useContext,useReducer} from "react"
const defaultState = {
a:'111',
b:'111'
}
const reducer = (state,action)=>{
let newState = {...state}
switch (action.type){
case 'CHANGE-A':
newState.a = action.value
return newState
case 'CHANGE-B':
newState.b = action.value
return newState
}
return state
}
const Global = React.createContext(null)
export default function FnReducer(){
// 通过解构获取useReducer中的state和dispatch方法
const [state,dispatch] = useReducer(reducer,defaultState)
return(
<Global.Provider value={
{state,dispatch}
}>
<div >
<Chilid1 />
<Chilid2 />
<Chilid3 />
</div>
</Global.Provider>
)
}
function Chilid1(){
const {dispatch} = useContext(Global)
return(
<div>
<button onClick={()=>{
dispatch({
type:'CHANGE-A',
value:'222'
})
}}>改变a</button>
<button onClick={()=>{
dispatch({
type:'CHANGE-B',
value:'333'
})
}}>改变b</button>
</div>
)
}
function Chilid2(){
const {state} = useContext(Global)
return(
<div>
{state.a}
</div>
)
}
function Chilid3(){
const {state} = useContext(Global)
return(
<div>
{state.b}
</div>
)
}
8、自定义hooks
为了让代码逻辑看起来结构清晰。我们可以把每个组件重复的逻辑单独抽出来,然后封装一个函数 然后return出来,只不过这个函数名必须以use开头。
以上就是hooks的理解与使用。