当前位置: 首页 > 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;

相关文章:

  • Linux安装vim超详细教程
  • Qt-QGroupBox容器类控件(39)
  • FortiGate 无线组网
  • Lucene 倒排索引原理详解:深入探讨相关算法设计
  • 精简解析:二叉树的遍历方法及其应用场景
  • 【TabBar嵌套Navigation案例-新特性页面-代码位置 Objective-C语言】
  • Git 撤销一个已经push到远端仓库的commit
  • 数据结构之栈和队列——LeetCode:150. 逆波兰表达式求值,224. 基本计算器,232. 用栈实现队列
  • 深度学习自编码器 - 得益于深度的指数增益篇
  • Qt-QTreeWidget多元素控件(38)
  • 复制他人 CSDN 文章到自己的博客
  • MK米客方德SD NAND参考设计
  • 【Linux篇】常用命令及操作技巧(进阶篇 - 上)
  • 短视频矩阵源码oem/矩阵系统搭建/源码开发注意事项知识分享
  • docker实践与应用举例
  • 【Leetcode】104. 二叉树的最大深度
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • JavaScript 基本功--面试宝典
  • JavaScript实现分页效果
  • js对象的深浅拷贝
  • Material Design
  • Nacos系列:Nacos的Java SDK使用
  • python大佬养成计划----difflib模块
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • Solarized Scheme
  • spark本地环境的搭建到运行第一个spark程序
  • XML已死 ?
  • 闭包,sync使用细节
  • 技术胖1-4季视频复习— (看视频笔记)
  • 讲清楚之javascript作用域
  • 两列自适应布局方案整理
  • 浏览器缓存机制分析
  • 配置 PM2 实现代码自动发布
  • 什么软件可以剪辑音乐?
  • 我的zsh配置, 2019最新方案
  • 白色的风信子
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​Linux·i2c驱动架构​
  • #define用法
  • #预处理和函数的对比以及条件编译
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (1)STL算法之遍历容器
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)ssm高校实验室 毕业设计 800008
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (南京观海微电子)——I3C协议介绍
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (新)网络工程师考点串讲与真题详解
  • (一) springboot详细介绍
  • (一)appium-desktop定位元素原理
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • (转) 深度模型优化性能 调参