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

useCallback()

官网直达:https://zh-hans.react.dev/reference/react/useCallback

点击按钮,子组件会重新渲染

import { memo, useState, useCallback } from 'react';const Child = (props) => {console.log('我是子组件!我在渲染呢!!!')return (<><div>我是子组件</div></>)
}const Parent = () => {console.log('我是父组件!我在渲染呢!!!')const [p1, setP1] = useState(0)const p2 = 'hello';const p3 = 'world';return (<><div>我是父组件,p1:{p1}</div><button onClick={() => {setP1(p1 + 1);}}>点我p1加1</button><Child p2={p2} p3={p3} /></>)
}export default Parent;

点击父组件的按钮,子组件也跟着渲染

使用memo()包裹子组件,如下

import { memo, useState, useCallback } from 'react';const Child = memo((props) => {console.log('我是子组件!我在渲染呢!!!')return (<><div>我是子组件</div></>)
});const Parent = () => {console.log('我是父组件!我在渲染呢!!!')const [p1, setP1] = useState(0)const p2 = 'hello';const p3 = 'world';return (<><div>我是父组件,p1:{p1}</div><button onClick={() => {setP1(p1 + 1);}}>点我p1加1</button><Child p2={p2} p3={p3} /></>)
}export default Parent;

这样父组件里的state变换就不会再渲染子组件了

使用memo()后会对props进行浅比较,如果props没有变化,则不会重新渲染子组件

现在要给子组建要传入一个函数p4,如下

import { memo, useState, useCallback } from 'react';const Child = memo((props) => {console.log('我是子组件!我在渲染呢!!!')return (<><div>我是子组件</div></>)
});const Parent = () => {console.log('我是父组件!我在渲染呢!!!')const [p1, setP1] = useState(0)const p2 = 'hello';const p3 = 'world';const p4 = () => {console.log(p2, p3)}return (<><div>我是父组件,p1:{p1}</div><button onClick={() => {setP1(p1 + 1);}}>点我p1加1</button><Child p2={p2} p3={p3} p4={p4} /></>)
}export default Parent;

现在添加p4,发现父组件的state变换,子组件也会重新渲染

说明p4变化了

这是因为p4是一个函数,每次渲染都会生成一个新的函数,导致props变化,从而触发子组件重新渲染

所以需要使用useCallback来缓存函数,确保是同一个函数

useCallback接受两个参数,第一个参数是函数,第二个参数是依赖项数组如下

同时在包裹函数的时候要在useCallback里传入函数所依赖的参数,

否则useCallback会认为函数没有依赖项,每次都会生成一个新的函数

import { memo, useState, useCallback } from 'react';const Child = memo((props) => {console.log('我是子组件!我在渲染呢!!!')return (<><div>我是子组件</div></>)
});const Parent = () => {console.log('我是父组件!我在渲染呢!!!')const [p1, setP1] = useState(0)const p2 = 'hello';const p3 = 'world';const p4 = useCallback(() => {console.log(p2, p3)}, [p2, p3])return (<><div>我是父组件,p1:{p1}</div><button onClick={() => {setP1(p1 + 1);}}>点我p1加1</button><Child p2={p2} p3={p3} p4={p4} /></>)
}export default Parent;

哎,这样就可以了,子组建没有重新渲染

来看下回调函数执行完之后会是怎样的一个结果

子组建执行props.p4()

如果回调里面要把p1log出来,会出现什么问题

只有第一次才会输出,p1改变不执行

应为函数p4被缓存了起来

依赖项是p2和p3,p1改变,不会触发p4重新生成

添加依赖项p1,p4重新生成,p1改变,p4重新执行

import { memo, useState, useCallback } from 'react';const Child = memo((props) => {console.log('我是子组件!我在渲染呢!!!')props.p4()return (<><div>我是子组件</div></>)
});const Parent = () => {console.log('我是父组件!我在渲染呢!!!')const [p1, setP1] = useState(0)const p2 = 'hello';const p3 = 'world';const p4 = useCallback(() => {console.log(p2, p3, p1)}, [p2, p3, p1])return (<><div>我是父组件,p1:{p1}</div><button onClick={() => {setP1(p1 + 1);}}>点我p1加1</button><Child p2={p2} p3={p3} p4={p4} /></>)
}export default Parent;

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

相关文章:

  • Python面试题精选及解析--第二篇
  • Linux操作常用问题
  • 汽车发动机系统(ems)详细解析
  • 对比学习训练是如何进行的
  • React 生命周期 - useEffect 介绍
  • OpenCV-指纹识别
  • IPD的核心思想
  • 如何在算家云搭建MVSEP-MDX23(音频分离)
  • 常用的Java安全框架
  • 使用 PHP 的 strip_tags函数保护您的应用安全
  • 您的计算机已被Lockbit3.0勒索病毒感染?恢复您的数据的方法在这里!
  • 经典sql题(十二)UDTF之Explode炸裂函数
  • 【AIGC】ChatGPT提示词解析:如何打造个人IP、CSDN爆款技术文案与高效教案设计
  • 【Ubuntu】Ubuntu常用命令
  • 架构设计笔记-5-软件工程基础知识-2
  • [网络]抓包工具介绍 tcpdump
  • 基于STM32和FPGA的射频数据采集系统设计流程
  • 自动变速箱系统(A/T)详细解析
  • 【Kubernetes】常见面试题汇总(四十三)
  • OpenCL 学习(1)---- OpenCL 基本概念
  • 自定义注解加 AOP 实现服务接口鉴权以及内部认证
  • 《软件工程概论》作业一:新冠疫情下软件产品设计(小区电梯实体按钮的软件替代方案)
  • 基于Ernie-Bot打造语音对话功能
  • 动手学深度学习(李沐)PyTorch 第 3 章 线性神经网络
  • ROS理论与实践学习笔记——2 ROS通信机制之服务通信
  • 技术成神之路:设计模式(十八)适配器模式
  • 图神经网络:处理复杂关系结构与图分类任务的强大工具
  • LeetCode: 1971. 寻找图中是否存在路径
  • mysql 查询表所有数据,分页的语句
  • TI DSP TMS320F280025 Note13:CPUtimer定时器原理分析与使用