React Hooks UseCallback

  开发环境:React Native + Taro + Typescript
useCallback的用途,主要用于性能优化:
1 避免不必要的子组件重渲染:当父组件重渲染时,如果传递给子组件的函数每次都是新创建的,即使子组件使用了 React.memo,也会导致子组件重新渲染。
2 作为其他 Hook 的依赖项:当函数被用作 useEffect、useMemo 或其他 Hook 的依赖项时,使用 useCallback 可以确保函数引用稳定,避免不必要的 effect 执行。
3 记忆化函数:对于创建成本较高的函数,使用 useCallback 可以避免在每次渲染时都重新创建。

    useCallback的优势:
1 性能优化:通过缓存函数实例,减少不必要的重渲染和函数创建,提高应用性能。
2 避免无限循环:在 useEffect 中使用函数时,如果函数没有使用 useCallback 包装,可能会导致无限重渲染。
3 稳定的函数引用:确保在依赖项不变的情况下,函数引用保持不变,这对于优化子组件渲染特别有用。

    使用时的注意事项:
1 不要过度使用:只有在确实需要优化性能时才使用 useCallback,因为useCallback本身也有性能开销。
2 正确设置依赖数组:确保依赖数组中包含所有在函数内部使用且可能变化的值,否则可能导致闭包问题。
3 与 React.memo 配合使用:useCallback 通常与 React.memo 一起使用才能发挥最大效果。

        下面是父组件:UseCallback

import React, { useState, useCallback, useEffect } from 'react'
import { View, Text, Button, ScrollView } from '@tarojs/components'
import styles from './plant.module.scss'
import Strawberry from './UseCallbackSub'const PlantManager: React.FC = ()=>{useEffect(()=>{console.log("父组件:useEffect, 组件重渲染!!!")})// 草本植物科目数量 初始化const [subjectNum, setSubjectNum] = useState(0)// 蔷薇科的植物或水果的颜色 初始化const [rosaceaeColor, setrosaceaeColor] = useState('green')// 蔷薇科的植物或水果size大小 初始化const [rosaceaeSize, setRosaceaeSize] = useState(5)// 蔷薇科植物或水果的颜色 改变次数,需要改变草莓颜色时,需要在此加一const [changeColorNum, setChangeColorNum] = useState(0)// 没有使用useCallback的函数,每次渲染都会创建新的函数实例const handleInrement = () => {console.log('父组件 handleInrement')// setSubjectNum(preSubjectNum => preSubjectNum + 1);}// 使用useCallback缓存函数,同样改变subjectNum的值const handleUseCallbackChangeSubjectNum = useCallback(()=>{console.log('父组件 handleUseCallbackChangeSubjectNum')// setSubjectNum(preSubjectNum => preSubjectNum + 1);}, []); //这里的依赖数组为空,是因为setSubjectNum是稳定的// 使用useCallback缓存函数,并带有依赖项// 改变子组件中草莓的颜色,并查看子组件渲染的时机与次数const handleChangeRosaceaeColor = useCallback(()=>{const color = rosaceaeColor === 'green' ? 'green' : 'red'setrosaceaeColor(color)}, [changeColorNum])const handleChangeColorNum = useCallback(()=>{setChangeColorNum(preNum => preNum + 1)}, [])// 使用useCallback缓存函数,没有依赖项// 改变子组件中草莓的size大小,并查看子组件渲染的时机与次数const handleChangeRosaceaeSize = useCallback(()=>{setRosaceaeSize(preSize => preSize + 1)}, [])return (<ScrollViewscrollYscrollWithAnimationclassName={styles.scroll}style={{height: '40vh',}}><View className={styles.container}><View className={styles.showTextBox}><Text>草本植物的数量 subjectNum = {subjectNum}</Text><Text>蔷薇科植物颜色需要改变的次数 = {changeColorNum}</Text><Strawberry color={rosaceaeColor}increment={handleInrement}changeSubjectNum={handleUseCallbackChangeSubjectNum}size={rosaceaeSize}></Strawberry></View><View className={styles.showTextBox}><Text className={styles.showText}>使用useCallback带有依赖项,改变子组件中草莓的颜色</Text><Button onClick={handleChangeRosaceaeColor} className={styles.actionBox} >改变子组件的草莓颜色</Button><Button onClick={handleChangeColorNum} className={styles.actionBox}>需要改变蔷薇科植物颜色时,给changeColorNum加一</Button></View><View className={styles.showTextBox}><Text className={styles.showText}>使用useCallback没有带依赖项,改变子组件中草莓size大小</Text><Button className={styles.actionBox} onClick={handleChangeRosaceaeSize}>改变子组件草莓的size</Button></View></View></ScrollView>)
}export default PlantManager

        下面是子组件:UseCallbackSub

import React, { useEffect, memo } from 'react'
import { View, Text, Button } from '@tarojs/components'
import styles from './plant.module.scss'interface StrawberryProps {color: stringsize: numberincrement: ()=>voidchangeSubjectNum: ()=>void
}// 定义一个子组件,用于查看子组件的更新状态const Strawberry: React.FC<StrawberryProps> = (props)=>{const { increment, changeSubjectNum } = props;useEffect(()=>{console.log("子组件重新渲染更新!!!")console.log("当前草莓的颜色: ", props.color);})return (<View className={styles.berryBox}><Text className={styles.showText}>子组件 草莓</Text><Text className={styles.berryTxt} style={{backgroundColor: props.color,}}>草莓的颜色</Text><Text className={styles.berryTxt}>草莓的大小size = {props.size}</Text><View className={styles.showTextBox}><Text className={styles.showText}>普通函数,没有使用useCallback缓存, 每次都会重新创建</Text><Button className={styles.actionBox} onClick={increment}>增加草本植物的数量</Button></View><View className={styles.showTextBox}><Text className={styles.showText}>使用useCallback缓存函数</Text><Button className={styles.actionBox} onClick={changeSubjectNum}>增加草本植物的数量</Button></View></View>)}// export default Strawberry;
export default memo(Strawberry);

        下面的文件是样式:

.container {margin-top: 30px;margin-bottom: 50px;margin-left: 15px;margin-right: 15px;padding: 20px;background-color: darkgrey;
}.scroll {margin-top: 30px;margin-bottom: 30px;margin-left: 15px;margin-right: 15px;
}.showTextBox {background-color: antiquewhite;padding: 10px;text-align: center;margin-bottom: 30px;
}.showText {padding: 20px;text-align: center;margin-top: 18px;background-color: cornflowerblue;
}.actionBox {background-color: aquamarine;padding: 20px;margin-top: 20px;
}.actionContainer {padding: 15px;margin-top: 30px;
}.berryBox {background-color: darksalmon;padding: 30px;
}.berryTxt {padding-left: 80px;padding-right: 80px;padding-top: 30px;padding-bottom: 30px;margin-bottom: 35px;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/98250.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/98250.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用SD为VFX制作贴图

1.制作遮罩 Gradient Linear 1 通过Blend 可以混合出不同遮罩 2.径向渐变 Shape 节点 , 非常常用 色阶调节灰度和渐变过渡 曲线能更细致调节灰度 色阶还可以反向 和圆盘混合 就是 菲涅尔Fresnel 3. 屏幕后处理渐变 第二种方法 4. 极坐标 Gradient Circular Threshold 阈值节…

面经分享二:Kafka、RabbitMQ 、RocketMQ 这三中消息中间件实现原理、区别与适用场景

一、实现原理 (Implementation Principle) 1. Apache Kafka&#xff1a;分布式提交日志 (Distributed Commit Log) Kafka 的核心设计理念是作为一个分布式、高吞吐量的提交日志系统。它不追求消息的复杂路由&#xff0c;而是追求数据的快速、持久化流动。 存储结构&#xff1a;…

Android开发——初步了解AndroidManifest.xml

Android开发——初步了解AndroidManifest.xml ​ AndroidManifest.xml 是 Android 应用的清单文件&#xff0c;包含了应用的包名、组件声明、权限声明、API 版本信息等。它是 Android 应用的“说明书”&#xff0c;系统通过它了解应用的结构和行为。咱们的AndroidManifest文件实…

ecplise配置maven插件

1.下载maven 2.配置系统变量 MAVEN_HOME&#xff1a; E:\CODE\MAVEN\apache-maven-3.0.4 3.配置环境变量 %MAVEN_HOME%\bin 4.cmd&#xff1a;mvn -version 注1 如图所示为&#xff1a;成功 注1&#xff1a;配置成功的前提是要有配置JAVA_HOME,如果没有配置&#xff0c;则…

Vue 项目性能优化实战

性能优化有一套「发现 → 定位 → 解决」的闭环方法论。本文以真实项目为蓝本&#xff0c;从编码阶段到上线监控&#xff0c;给出一条可落地的 Vue 性能优化路线图。 一、量化指标定位性能瓶颈 任何优化之前先用量化证据锁死问题。 Lighthouse 一键跑分&#xff1a;首屏、交互、…

阿里云智能多模态大模型岗三面面经

阿里云智能多模态大模型岗三面面经&#xff08;详细问题感受&#xff09; 最近面试了 阿里云智能集团 - 多模态大模型岗位&#xff0c;三轮技术面&#xff0c;整体体验还不错。问题整体偏常规&#xff0c;但对项目的追问比较细致。这里整理一下完整面经&#xff0c;供准备类似岗…

C++ 条件变量 通知 cv.notify_all() 先释放锁再通知

简短的回答是&#xff1a;先释放锁&#xff0c;再通知&#xff08;notify_one 或 notify_all&#xff09;通常是更优的选择。 虽然标准允许两种顺序&#xff0c;但“先解锁&#xff0c;后通知”的性能通常更好。 下面我们来详细解释原因和两种方式的区别。 先通知&#xff0c;后…

案例精选 | 南京交通职业技术学院安全运营服务建设标杆

导语 随着教育信息化的深入推进&#xff0c;高校已成为数字化转型的前沿阵地。然而&#xff0c;伴随着教学、科研、管理等业务系统的全面上云与互联互通&#xff0c;高校网络环境日益复杂&#xff0c;面临的网络安全威胁也愈发严峻。勒索病毒、数据泄露、APT攻击等安全事件频发…

AI安全必修课:模型偏见检测与缓解实战

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 引言&#xff1a;AI偏见——看不见的技术债务 2018年&#xff0c…

Trae + MCP : 一键生成专业封面

每日一句 人生只有走出来的美丽&#xff0c; 没有等出来的辉煌。 目录 每日一句 前言 一.核心工具与优势解析 二.操作步骤&#xff1a;从配置到生成广告封面 前期准备&#xff1a;确认环境与工具版本 第一步. 获取配置代码 第二步&#xff1a;在 Trae 中导入 MCP 配置…

Eureka与Nacos的区别-服务注册+配置管理

Eureka与Nacos的区别-服务注册配置管理 以下是 Eureka 和 Nacos 的核心区别对比&#xff0c;帮你清晰理解它们的不同定位和特性&#xff1a; ​1. 核心定位​ ​Eureka&#xff1a;​​ ​纯服务注册与发现中心&#xff0c;源自 Netflix&#xff0c;核心功能是维护服务实例清单…

这才是真正懂C/C++的人,写代码时怎么区分函数指针和指针函数?

1.介绍 很多初中级开发者常常在这两个术语之间感到困惑,分不清它们的定义、语法和应用场景,从而在实际编程中埋下隐患。本文旨在拨开迷雾,从概念定义、语法解析、核心区别及实战应用四个维度,对函数指针与指针函数进行一次全面、深入的辨析,帮助您彻底厘清这两个概念,并…

Go基础(④指针)

简单示例package mainimport "fmt"func main() {var num int 100var p *int &num // 指向int类型的指针fmt.Println(*p) // 解引用&#xff0c;输出 100*p 200 // 通过指针修改原变量fmt.Println(num) // 输出 200 }package mainimport "fmt…

java社交小程序源码支持APP多端springboot部署与功能模块详解

构建一个支持 多端访问、实时互动、商城交易 的综合型应用&#xff0c;已成为众多企业和开发团队的共同目标。由 宠友信息技术有限公司 打造的 友猫社区&#xff0c;正是基于 Spring Boot 技术栈 的全端解决方案&#xff0c;既能支持 微信小程序、APP、PC管理后台&#xff0c;又…

代理连接性能优化:提升网络效率的关键技术与实践

在当今数字化时代&#xff0c;代理连接性能优化已成为网络架构设计中的关键环节。本文将深入探讨如何通过技术手段提升代理服务器的响应速度、稳定性和资源利用率&#xff0c;帮助读者构建高效可靠的代理网络体系。 代理连接性能优化&#xff1a;提升网络效率的关键技术与实践 …

Rust 元组

简介 元组可以由多种类型组成&#xff0c;长度固定。 创建元组 // 固定类型 let tup1: (i32, f64, u8) (500, 8.8, 1);// 不固定类型 let tup2 (500.99, 8.8, 1, 9.99);println!("{}", tup2.0);用模式匹配解构元组 let tup (500.99, 8.8, 1, 9.99); let (x, y…

突破闭集限制:3D-MOOD 实现开集单目 3D 检测新 SOTA

【导读】 单目 3D 目标检测是计算机视觉领域的热门研究方向&#xff0c;但如何在真实复杂场景中识别“未见过”的物体&#xff0c;一直是个难题。本文介绍的 3D-MOOD 框架&#xff0c;首次提出端到端的开集单目 3D 检测方案&#xff0c;并在多个数据集上刷新了 SOTA。 目录 …

Python爬虫数据清洗实战:从杂乱无章到整洁可用

小伙伴们&#xff0c;做爬虫最头疼的不是抓数据&#xff0c;而是抓回来那一堆乱七八糟的内容&#xff01;价格里混着符号、日期格式千奇百怪、还有重复和缺失的值&#xff0c;看着就头大。别慌&#xff0c;咱们用Python几招就能搞定。Pandas处理表格数据是真香&#xff0c;正则…

打工人日报#20250906

打工人日报#20250906 周六了&#xff01; 今天出门读者特别痛&#xff0c;本来都想爽约了&#xff0c;不过忍下来了了&#xff0c;现在看来很值得&#xff01; 不过还是要好好吃早餐、和热水&#xff01; 阅读 《小米创业思考》 第一章 奇迹时代 看完了 就是快呀 好的产品 好的…

小型磨床设计cad+三维图+设计说明书

摘 要 随着现代加工技术的发展&#xff0c;各种各样的加工技术得到了广泛的应用&#xff0c;磨床在机械制造领域得到了广泛的应用&#xff0c;本文经过查阅相关文献&#xff0c;完成了一种小型磨床的结构设计。 本文设计的小型磨床其主要是由三部分组成的&#xff0c;第一部分…