useCallback和useMemo

或许大家都明白useCallback一个这样的作用,为了性能优化,但是怎么去用它才能达到性能优化呢,因为我曾经看到过有同事,碰到点击事件就用useCallback包裹起来,但是这样真的是能优化吗,今天我们就来捋一捋

useCallback(() => {}, [a, b]);

useCallback会返回一个函数的memoized值;

无依赖时,执行原来的函数;依赖项改变时,函数进行一个更新,在依赖不变的情况下,多次定义的时候,返回的值是相同的。

有些人可能会误以为 useCallback 可以用来解决创建函数造成的性能问题,其实恰恰相反,单从这个组件看的话 useCallback 只会更慢,因为 inline 函数是无论如何都会创建的,还增加了 useCallback 内部对 inputs 变化的检测。

我们先来看一段代码:

  
const add1= () => {
    console.log("add1");
    setCount(num+ 1);
  }
 
  const add2= useCallback(() => {
    console.log("add2");
    setNum(num+ 1);
  }, [num])

1.当页面重新渲染时,会重新创建一个add函数

2.虽然我们add2用useCallback,但是页面重新渲染时,依然要执行useCallback后面的代码,只是返回的值相同,照样还是会创建一个函数

所以综上分析看来,这种情况下根本无法达到性能优化,我们千万不要掉进 useCallback 可以用来解决创建函数造成的性能问题的坑

那么,到底useCallback到底在什么时候用呢

场景:将父组件的函数,传给子组件作为回调使用时

export default function testCallBack() {
  const [num, setNum] = useState(0);
  const add1= () => {
    setCount(num+ 1);
  }
  const add2= useCallback(() => {
    setNum(num+ 1);
  }, [num])
  return (
    <div>
      <Son increment={add1} />
      <Son increment={add2} />
    </div>
  )
}
const Son = memo((props) => {
  console.log('子组件加载')
  return <div onClick={props.add}>add1</div>
})

注意:memo:进行浅层比较,有更新就渲染,没更新不渲染,这里不过多阐述了

1.当父组件重新渲染时,父组件内add1重新创建,那传到子组件的时候,检测到有变化,所以渲染子组件

2.当父组件重新渲染时,父组件内也会add2重新创建,但是他使用了useCallback,依赖没有发生变化时,那useCallback就会返回相同的值,那add2的值就没有变化,memo检测到add2没有变化,就不更新子组件

以上就阐述完成useCalllback的用法和执行过程,得出结论:

useCallback的作用:配合memo用于优化子组件的渲染次数

下面在进行类组件同类问题的扩展上述代码,每次带你家ParentComponent就会导致ChildrenComponent也渲染一次,虽然ChildrenComponent采用了PureComponent 优化

在使用类组件的时候,使用不当,也会存在这样的问题

当父组件组件的setate发生改变的时候 render都会重新渲染一次,子组件的属性 handleChildren属性采用匿名函数赋值,导致每次的引用地址不一样,那么ChildrenComponent使用用PureComponent 优化是无效的

优化

  <SonComponent
      handleChildren={() => {
        this.handleParent();
      }}
    />

//替换成
 <SonComponent handleChildren={this.handleParent()} />

点击父组件不会导致子组件也渲染,真正的起到了优化的作用

useMemo使用场景

优化针对于当前组件高开销的计算,具有记忆功能,

假如页面上有一个比较大的高开销的计算,每次set一个值的时候,都会重新执行计算函数,这样的话,很占内存,这时候可以用到useMemo

例如

// 假设computedNum()是一个计算量非常大的函数
const computeValue = useMemo(() => computedNum(num), [num]);

两者的区别

useCallback 对于子组件渲染优化

useMemo 对于当前组件高开销的计算优化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值