当前位置: 首页 > news >正文

React 第十六节 useCallback 使用详解注意事项

useCallback 概述

1、useCallback 是在React 中多次渲染缓存函数的 Hook,返回一个函数的 memoized的值;
2、如果多次传入的依赖项不变,那么多次定义的时候,返回的值是相同的,防止频繁触发更新;
3、多应用在 父组件为函数式组件,子组件也为函数式组件,并且子组件被 React.memo() 包裹着;
4、主要用于性能优化,即使不适用useCallback,代码也要能正常运行;

useCallback 基本用法

写法

let memoizedCallback = useCallback(fn, dependencies)

第一个参数fn 是想要缓存的函数,可以接收任何参数并返回任何值;React 中会在初始化时候调用,而不是渲染时候调用;
当执行下一次渲染时候,如何出入的依赖值 dependencies 相同,则会返回相同的函数 memoizedCallback
相反 若依赖值 dependencies 不同,则会返回新的函数 memoizedCallback,但是 React 不会主动去调用 memoizedCallback函数,需要开发者自己决定什么时候执行调用函数;

第二个参数
dependencies:是否要更新 fn 的所有响应式值的一个列表,可以传入空数组:[]
响应式值包括 props、state,和所有在你组件内部直接声明的变量和函数。

useCallback 示例

1、为什么要使用 useCallback

当我们传入相同值的时候,不管是对象类型,还是基本类型,都不希望子组件进行更新渲染;
在不需要大量渲染的时候,性能还可以,但是当数据量大的时候,若相同的数据也触发子组件渲染,则会出现性能问题;

2、在不使用 useCallback() 的时候

每次触发 handleAdd 事件时候,都会渲染子组件 ChildA

//  父组件
import { useCallback,  useState} from 'react'
import ChildA from './childA'
export default function MyCallBack() {const [useInfo, setUseInfo] = useState({name: 'Andy',age: 18})const myCallback = () => {console.log('==useCallback==')return useInfo.name}const handleAdd = () => {setUseInfo({name: 'Andy',age: 18})}return (<div><h3>This is a MyCallBack demo .---{count}</h3><button onClick={handleAdd}>add</button><hr /><ChildA  onAddCount={myCallback} ></ChildA></div>)
}
// 子组件
import React, { memo } from 'react'const  ChildA = memo(({onAddCount}) => {console.log('==ChildA 组件更新了=', count)return (<div><h3>This is a ChildA demo .</h3><button onClick={onAddCount}>子组件</button><hr /></div>)
})

当我们点击 add 按钮时候,发现页面打印 “==ChildA 组件更新了=”,说明传入相同的数据时候,会触发子组件渲染;如图所示

在这里插入图片描述

3、使用 useCallback 时候

import { useCallback,useState} from 'react'
import ChildA from './childA'
export default function MyCallBack() {console.log('===父组件callback==')const [count, setCount] = useState(0)const [useInfo, setUseInfo] = useState({name: 'Andy',age: 18})const myCallback = useCallback(() => {console.log('==useCallback==')return useInfo.name}, [useInfo.name])const handleAdd = () => {setUseInfo({name: 'Andy',age: 18})}return (<div><h3>This is a MyCallBack demo .---{count}</h3><button onClick={handleAdd}>add</button><hr /><ChildA  onAddCount={myCallback} ></ChildA></div>)
}
// 子组件
import { memo } from 'react'
// eslint-disable-next-line react/display-name
const  ChildA = memo(({useInfo, count, onAddCount}) => {console.log('==ChildA 组件更新了=', count)const handleChangeName = () =>{setName('Tom')}return (<div><h3>This is a ChildA demo .</h3><h4>{count}</h4><h4>姓名:{useInfo?.name || '--'}</h4><h4>年龄:{useInfo?.age || '--'}</h4><button onClick={onAddCount}>子组件</button><hr /></div>)
})
export default  ChildA 

在点击 add 按钮 更新相同数据时候,只有父组件渲染子组件不会再渲染;如图:在这里插入图片描述

总结

若要实现 传入相同数据时候,只更新当前组件,而子组件不进行渲染,需使用 useCallback() 和 memo 来处理

http://www.lryc.cn/news/503484.html

相关文章:

  • 使用C#和OPenCV实现圆形检测
  • 评估一套呼叫中心大模型呼入机器人的投入回报比?
  • 十八、Label 和 Selector
  • 实现按键按下(低电平)检测到下降沿
  • 解析 SSM 垃圾分类系统,助力生态平衡
  • 软件工程 设计的复杂性
  • Nginx 限制只能白名单 uri 请求的配置
  • QT c++ 同时使用sqlite 和mysql数据库的问题
  • redis集群 服务器更换ip,怎么办,怎么更换redis集群的ip
  • 【C++习题】19.数组中第K个大的元素
  • JIS-CTF: VulnUpload靶场渗透
  • BGP-面试
  • Git-安装与常用命令
  • 回归预测 | Matlab实现基于BiLSTM-Adaboost双向长短期记忆神经网络结合Adaboost集成学习回归预测
  • 微信小程序跳转其他小程序以及跳转网站
  • Not using native diff for overlay2, this may cause degraded performance……
  • 【自用】管材流转项目 数据库恢复之 PIPE 表 二维码相关 各个表恢复 SQL
  • 【渗透测试】信息收集二
  • 测试工程师八股文04|计算机网络 和 其他
  • 定时/延时任务-Kafka时间轮源码分析
  • 如何用状态图进行设计05
  • 【计算机视觉】边缘检测
  • 林曦词典|无聊
  • LabVIEW光栅衍射虚拟仿真系统
  • 【NumPy进阶】:内存视图、性能优化与高级线性代数
  • 从YOLOv5到训练实战:易用性和扩展性的加强
  • Prim 算法在不同权重范围内的性能分析及其实现
  • canal安装使用
  • python爬虫常用数据保存模板(Excel、CSV、mysql)——scrapy中常用数据提取方法(CSS、XPATH、正则)(23)
  • You need to call SQLitePCL.raw.SetProvider()