这是我对到目前为止我常用的以及看文档看到的一些react hooks的总结:
useState:
功能:这是react为函数组件创造的专门用来处理state的方法
用法:const [num,setNum] = setState(你要传的状态的值)
参数:这个方法返回一个读:num,一个写的值:setNum,setNum本质上是一个回调函数,他需要你传入参数
注意事项:
1.这个方法并不能关注到局部更新,比如对象内部的值变了,它无法察觉出来
2.更新对象的时候,如果前后传入的值相同,则无法引起渲染
useEffect:
功能:这个东西名字叫副作用,其实就是拿来监测组件中哪些状态在组件刷新的时候产生变化的
用法:useEffect(()=>{这是个回调函数,在组件刷新的时候被调用},[这边写上你要监听的状态])
参数:useEffect需要你传入一个回调函数,一个用于监听的数据。最后,你有时候需要在第一个回调函数中写一个return,传入一个回调函数,用在组件被销毁的时候使用,
类似:类似功能的还有一个useLayoutEffect,这个的区别在于这个useLayoutEffect会在组件被渲染前调用
注意事项:
useEffect常常被用来模拟生命周期。下面给出模拟生命周期的代码
componentDidUpdate:
const useUpdate = (fn,deps)=>{
const isFirst = useRef(true);
useEffect(()=>{
if (isFirst.current === true){
isFirst.current = false;
}else {
fn()
}
},[fn,deps])
}
componentDidMount:
useEffect(fn,[])
shouldComponentUpdate:用memo
componentWillUnmount:
useEffect(()=>{return fn},)
useContext:
功能:这是用来将组件的上层树中的状态传给下层树组件
用法:这个方法经常有两个方法,一个是createContext,一个是useContext.这两个的写法如下
const Context = createContext("") //一般传个空值,这个如果传值,一般只在测试的时候用
function App(){
return (
<Context.Provider value={xxx}>
<Demo/>
<Context.Provider>
)
}
function Demo(){
const {xxx} = useContext(Context)
return (
<div>showContext</div>
)
}
参数:传入一个value,里面可以是对象或者其他别的,这样子组件就能拿到
这玩意平常还能跟useReducer连用,模拟redux
useReducer
功能:react官方对redux作出的模拟函数,跟useState类似,获得一个读接口和一个写接口
用法:见如下代码
const initState = 1;
const reducer = (state,action)=>{
const {type,data} = action;
switch (type){
case "case1":
return data+state
case "case2":
return state-data
default:
return state
}
}
function App(){
const [state,dispatch] = useReducer(reducer,initState)
return (
<div>
showState {state}
<button onClick={()=>{dispatch({type:"case1",data:1})}}>+1</button>
<button onClick={()=>{dispatch({type:"case2",data:1})}}>-1</button>
</div>
)
}
参数:它需要两个或者三个参数,第一个一般固定式reducer,也就是对传入的值进行各种操作的地方。第二个是要初始的值,如果传入的初始值是一个函数,那么将函数传第三个,第二个作为函数的初始值传入。
这个方法一般跟useContext连用,模拟redux,在redux一块中已有代码实现。
useRef:
功能:用来在组件中创造一个独立的量,他能在组件中保持不变
用法:const ref = useRef(你要传的值)
参数:需要在ref中传入你想要传的值,注意在读取ref的值是需要使用current来读取,直接读取是得不到的,因为它本质是在内存中开辟了一个对象来存储,这样组件更新就将这个对象的地址值传给新的ref的地址值
useMemo:
功能:用来优化代码,使得带有函数的组件免去不必要的重新render
用法:const NewComponent = useMemo(OldComponent)
给段实际的代码示例
function App(){
const [n,setN] = useState(0);
const [m,setM] = useState(0)
return (
<div>
app
<Child1 n={n} changeN={(num)=>{setN(num+n)}}/>
<Child2 m={m} changeM={(num)=>{setM(num+m)}}/>
</div>
)
}
function Child1(props){
console.log(1);
return (
<div>
{props.n}
<button onClick={()=>{props.changeN(10)}}>+10</button>
</div>
)
}
const Child2 = memo((props)=>{
const {m,changeM} = props;
console.log(2);
return (
<div>
{m}
<button onClick={()=>{changeM(10)}}>+10</button>
</div>
)
});
这段代码很奇怪,我明明已经用memo优化了原有的代码,为什么每次app被render时候还会再执行一次呢?原因就在于他传了一个props的函数,函数的值在app内,所以还会再次执行,于是我们使用useMemo对函数内的fn进行优化。
+ const onClick = useMemo(()=>{
return (data)=>{setM(m+data)}
},[m])
- <Child2 m={m} changeM={(num)=>{setM(num+m)}}/>
+ <Child2 m={m} changeM={onClick}/>
用useMemo包一层,就很好的解决了
类似:这个方法类似的还有useCallBack,区别在于它们的调用方式不一样,useCallBack直接把要调回的函数写上去了,相当于()=>{fn},而useMemo要写两层()=>{return ()=>{fn}}
自定义hooks:
hooks最大的变化莫过于带来了自定义hooks组件,从此我们可以用函数式编的方法来写react,用它来代替redux可以说是方便至极