结合memo简述useCallback的使用场景

本文介绍了React中的useCallbackHook,用于在多次渲染时缓存函数,防止因父组件状态改变导致子组件频繁渲染的问题。通过与React.memo的对比,展示了useCallback如何通过依赖数组控制函数的创建和更新,提高性能。
摘要由CSDN通过智能技术生成

先看一下官方对于useCallback的定义:

useCallback是一个允许你在多次渲染中缓存函数的React Hook

这句话包含了俩个因素:

  • useCallback的作用:缓存函数
  • useCallback的使用场景:多次渲染下

什么叫多次渲染呢?组件嵌套的时候会存在多次渲染,如下:

import React, { useState, useCallback, memo} from 'react';


const Child = (props) => {
    console.log('子组件渲染了')
    const {childCount} = props;
    return (
        <div>
            <h1>子组件:{childCount}</h1>
        </div>
    )
}

const Parent = () => {
    console.log('父组件渲染了')
    const [count, setCount] = useState(0);
    const [childCount, setChildCOunt] = useState(0)
    return (
        <div>
            <h1>父组件:{count}</h1>
            <button onClick={()=>{setCount(count+1)}}>点击父组件值加一</button>
            <Child childCount={childCount}/>
        </div>
    )
}
export default Parent;

在这里插入图片描述

通过这个例子,我们能看到,当父组件中的state发生变化的时候,子组件也会触发渲染,即使变化的state并没有作为props传入子组件

如何解决这个问题呢?React.memo登场,只需要将Child用memo包裹,如下:

const Child = memo((props) => {
    console.log('子组件渲染了')
    const {childCount} = props;
    return (
        <div>
            <h1>子组件:{childCount}</h1>
        </div>
    )
})

memo 允许你的组件在 props 没有改变的情况下跳过重新渲染(注意默认是浅比较)
但是如果传入子组件的props中包含了一个函数的话,会发生什么事呢?

import React, { useState, useCallback, memo} from 'react';


const Child = memo((props) => {
    console.log('子组件渲染了')
    const {childCount,watchChildCount} = props;
    //执行传入的watchChildCount
    watchChildCount()

    return (
        <div>
            <h1>子组件:{childCount}</h1>
        </div>
    )
})

const Parent = () => {
    console.log('父组件渲染了')
    const [count, setCount] = useState(0);
    const [childCount, setChildCount] = useState(0)

    //给子组件传入一个函数
    const watchChildCount = () => {
        console.log(childCount,'打印childCount')
    }
    return (
        <div>
            <h1>父组件:{count}</h1>
            <button onClick={()=>{setCount(count+1)}}>点击父组件值加一</button>
            <Child childCount={childCount} watchChildCount={watchChildCount}/>
            <button onClick={() => {setChildCount(childCount+1)}}>点击子组件值加一</button>
        </div>
    )
}
export default Parent;

此时你再点击 父组件值加一 的这个按钮,会发现,即使子组件已经被memo包裹了,子组件还是触发了渲染

这是因为,组件每次渲染的时候,其中的函数都会被重新创建,React.memo使用的是浅比较,所以看似作为props的fn没有发生变化,其实它已经是一个新的fn了

如何解决这个问题呢?useCallback登场

const watchChildCount = useCallback(() => {
    console.log(childCount,'打印childCount')
},[childCount])

useCallback能够将函数缓存起来,只依赖于给定的状态值来确定该函数是否需要重新创建,避免父组件每次更新都创建的这种情况

以上代码都是即粘即用的,感兴趣的可以自己cra一个react项目,去试一下

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值