常用hook使用

112 阅读2分钟
  1. Hooks的由来是什么?

  2. useRef的高级用法是什么?

  3. useMemo 和 useCallback 是怎么做优化的?

  4. useRef 缓存数据

什么是react hook

react-hooks是React16.8以后新增的钩子API,目的是增加代码的可复用性、逻辑性,最主要的是解决了函数式组件无状态的问题。

那么什么是自定义hooks呢?

自定义hooks是在react-hooks基础上的一个扩展,可以根据业务、需求去制定相应的hooks,将常用的逻辑进行封装,从而具备复用性

useMemo

只要父组件的状态更新,无论有没有对自组件进行操作,子组件都会进行更新,useMemo就是为了防止这点而出现的。

useMemo(() => (
        <div>
            {
                list.map((item, index) => (
                    <p key={index}>
                        {item.name}
                    </>
                )}
            }
        </div>
    ),[list])

从上面我们看出 useMemo只有在list发生变化的时候才会进行渲染,从而减少了不必要的开销

总结一下useMemo的好处

  1. 可以减少不必要的循环和不必要的渲染
  2. 可以减少子组件的渲染次数
  3. 通过特地的依赖进行更新,可以避免很多不必要的开销,但要注意,有时候在配合 useState拿不到最新的值,这种情况可以考虑使用 useRef解决

useCallback

useCallback与useMemo极其类似,可以说是一模一样,唯一不同的是useMemo返回的是函数运行的结果,而useCallback返回的是函数

注意:这个函数是父组件传递子组件的一个函数,防止做无关的刷新,其次,这个组件必须配合memo,否则不但不会提升性能,还有可能降低性能

import React, { useState, useCallback } from 'react';
import { Button } from 'antd-mobile'; 
const MockMemo: React.FC<any> = () => { 
const [count,setCount] = useState(0)
const [show,setShow] = useState(true)
const add = useCallback(()=>{ setCount(count + 1) }, [count] );
    return ( <div> 
        <div style={{display: 'flex', justifyContent: 'flex-start'}}> 
            <TestButton title="普通点击" onClick={() => setCount(count + 1) }/>
            <TestButton title="useCallback点击" onClick={add}/>
            </div> <div style={{marginTop: 20}}>count: {count}</div>
            <Button onClick={() => {setShow(!show)}}> 切换</Button> 
       </div> ) 
} 
const TestButton = React.memo((props:any)=>{ 
        console.log(props.title) 
        return <Button color='primary' onClick={props.onClick} style={props.title === 'useCallback点击' ? { marginLeft: 20 } : undefined}>
        {props.title}</Button> 
}) 
export default MockMemo;

useRef

缓存数据

除了获取对应的属性值外,useRef还有一点比较重要的特性,那就是 缓存数据

useRef 可以拿到最新值,我们可以进行简单的封装,这样做的好处是:可以随时确保获取的是最新值,并且也可以解决闭包问题

import { useRef } from 'react'; 

const useLatest = <T>(value: T) => { 
   const ref = useRef(value) 
   ref.current = value return ref
 };
 export default useLatest;