react 必备的知识:useMemo和useCallback的使用

大家好,我叫小杜杜,随着Hooks的盛行,我们要想在项目中灵活使用,就必须了解其内部原理,并且学会使用方法,今天来详细看看useMemouseCallback这两个钩子

useMemo

当一个父组件中调用了一个子组件的时候,父组件的 state 发生变化,会导致父组件更新,而子组件虽然没有发生改变,但也会进行更新。

简单的理解下,当一个页面内容非常复杂,模块非常多的时候,函数式组件会从头更新到尾,只要一处改变,所有的模块都会进行刷新,这种情况显然是没有必要的。

我们理想的状态是各个模块只进行自己的更新,不要相互去影响,那么此时用useMemo是最佳的解决方案。

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

在讲 useMemo 之前,我们先说说memo,memo的作用是结合了pureComponent纯组件和 componentShouldUpdate功能,会对传入的props进行一次对比,然后根据第二个函数返回值来进一步判断哪些props需要更新。(具体使用会在下文讲到~)

useMemomemo的理念上差不多,都是判断是否满足当前的限定条件来决定是否执行callback函数,而useMemo的第二个参数是一个数组,通过这个数组来判定是否更新回掉函数

这种方式可以运用在元素、组件、上下文中,尤其是利用在数组上,先看一个例子:

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

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

总结一下useMemo的好处:

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

useCallback

useCaackuseMemo极其类似,可以说是一模一样,唯一不同的是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; 

img2.gif

我们可以看到,当点击切换按钮的时候,没有经过 useCallback封装的函数会再次刷新,而进过过 useCallback包裹的函数不会被再次刷新

End

最后,一定要有效的利用 useRef去结合useMemouseCallback做性能优化,写出高质量的组件,一定要多多实现,喜欢的点个👍吧~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值