React的useCallback作用

1,105 阅读1分钟

简述

在React的官网中,我们可以看到其实useMemouseCallback可以说是同一个东西,详细介绍可看官网,这里以一个小demo来举例useCallback

useCallback(fn,[deps]) === useMemo(()=> fn ,[deps])

代码

import React, { FC, useCallback, useState } from 'react'
import {Button} from 'antd'
const KnowHooks:FC = () => {
  const [count1 ,setCount1] = useState<number>(0)
  const [count2 ,setCount2] = useState<number>(0)
  const [count3 ,setCount3] = useState<number>(0)
  const btn1ClickHandle = ()=> {
    setCount1(count1 + 1)
  }
  const btn2ClickHandle = useCallback(()=> {
    setCount2(count2 + 1)
  },[count2])
  return (
    <div>
      <Child btnClickHandle={btn1ClickHandle}>
        button1
      </Child>
      <br />
      <Child btnClickHandle={btn2ClickHandle}>
        button2
      </Child>
      <br />
      <Child btnClickHandle={()=>{
        setCount3(count3+1)    
      }}>
        button3
      </Child>
      <br />
    </div>
  )
}
​
const Child:FC<ChildProps<string>> = React.memo((props = {}) => {
  const {children,btnClickHandle} = props
  return (
    <>
      <Button onClick={btnClickHandle}>{children}</Button>
      <span>{Math.random()}</span>
    </>
  )
})
​
interface ChildProps<T=any> {
  btnClickHandle?():void
  children?:T
}
​
export default KnowHooks

代码中可以看到Child用了React.memo来包裹返回的函数组件

React.memo的作用:具有缓存作用,如果props的值没有发生变化,那么它包裹的函数组件会进行缓存,类似于vuecomputed属性

它跟useMemo很像,区别就是,useMemo有第二个参数可以传入依赖哪些变量进行缓存,而React.memo是依赖于所有props

效果

useCallback.gif

从以上效果图我们可以看出,当我们点击button1与button2的时候,只有一、三的值会变,而当我点击了button2的时候,三个值都会发生改变,因为用了useCallback包裹的函数,它依赖于count2的改变,当count2的值没有发生改变的时候,那它的函数就会进行缓存,而因为这个函数缓存了,那传入Child后,child的props拿到的这个btnClickHandle是缓存的(也就是上一次的,没有变化),所以这个组件的props没变,所以它不会重新渲染

结论

由此可以看出useCallback在一定程度上是有性能优化的作用的