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

【前端知识】React 基础巩固(四十四)——其他Hooks(useContext、useReducer、useCallback)

React 基础巩固(四十四)——其他Hooks(useContext、useReducer、useCallback)

一、useContext的使用

在类组件开发时,我们通过 类名.contextType = MyContext的方式,在类中获取context,多个Context或者在函数式组件中通过MyContext.Consumer方式共享context:

import React, { memo } from 'react'
import { UserContext, ThemeContext } from './context'export default memo(function App() {// 使用Contextreturn (<div><UserContext.Consumer>{value => {return (<h2><ThemeContext.Consumer>{value => {<span></span>}}</ThemeContext.Consumer></h2>)}}</UserContext.Consumer></div>)
})

可以看到,当我们需要使用多个Context时,存在大量繁琐的嵌套代码;而Context Hook能够让我们通过Hook直接获取某个Context的值,如下:

import React, { memo, useContext } from "react";
import { ThemeContext, UserContext } from "./context";export default memo(function App() {// 使用Contextconst user = useContext(UserContext);const theme = useContext(ThemeContext);return (<div><h2>User: {user.name} - {user.age}</h2><h2>Theme: {theme.color} - {theme.size}</h2></div>);
});

可以看到,Context Hook仅用了两行代码就替代了上面繁杂的嵌套代码,十分高效简洁。

二、useReducer的使用

useReducer是useState的一种替代方案,当state的处理逻辑比较复杂,可以使用useReducer来进行拆分,或者当修改state时需要依赖之前的state时,也可以使用useReducer。

useReducer使用的场景非常少,通常用于需要统一管理、修改多个数据的场景。例如,当我们需要对多个数据进行统一处理时,若采用useState,则需要多次定义,而reducer可以对其进行统一定义、修改:

import React, { memo, useReducer, useState } from "react";function reducer(state, action) {switch (action.type) {case "increment":return { ...state, counter: state.counter + 1 };case "decrement":return { ...state, counter: state.counter - 1 };case "add_number":return { ...state, counter: state.counter + action.num };case "sub_number":return { ...state, counter: state.counter - action.num };default:return state;}
}export default memo(function App() {// const [count, setCount] = useState(0);// const [user, setUser] = useState(0);// const [list, setList] = useState(0);const [state, dispatch] = useReducer(reducer, {counter: 0,user: {},list: [],});return (<div>{/* <h2>当前计数:{count}</h2><button onClick={(e) => setCount(count + 1)}>+1</button><button onClick={(e) => setCount(count - 1)}>-1</button><button onClick={(e) => setCount(count + 5)}>+5</button><button onClick={(e) => setCount(count - 5)}>-5</button><button onClick={(e) => setCount(count + 100)}>+100</button> */}<h2>当前计数:{state.counter}</h2><button onClick={(e) => dispatch({ type: "increment" })}>+1</button><button onClick={(e) => dispatch({ type: "decrement" })}>-1</button><button onClick={(e) => dispatch({ type: "add_number", num: 5 })}>+5</button><button onClick={(e) => dispatch({ type: "sub_number", num: 5 })}>-5</button><button onClick={(e) => dispatch({ type: "add_number", num: 100 })}>+100</button></div>);
});

三、useCallback的使用

useCallback实际的目的是为了进行性能优化,useCallback会返回一个函数的memoized(记忆的)值。在依赖不变的情况下,多次定义的时候,返回的值时相同的。

useCallback的性能优化:

  1. 当需要将一个函数传递给子组件时,可使用useCallback进行优化,将优化之后的函数,传递给子组件

    import React, { memo, useCallback, useState } from "react";const HYIncrement = memo(function (props) {const { increment } = props;console.log("HYIncrement被渲染");return (<div><button onClick={increment}>increment + 1</button></div>);
    });export default memo(function App() {const [count, setCount] = useState(0);const [message, setMessage] = useState("hello");// 使用useCallbackconst increment = useCallback(function () {setCount(count + 1);},[count]);// 普通函数// const increment = () => {//   setCount(count + 1);// };return (<div><h2>计数:{count}</h2><button onClick={increment}>+1</button><HYIncrement increment={increment} /><h2>message:{message}</h2><button onClick={(e) => setMessage("world")}>修改 message</button></div>);
    });
  2. 进一步优化

    当count发生改变时,也使用同一个函数

      // 做法一:将count依赖移除掉,缺点:存在闭包陷阱,不依赖count后setCount每次拿到的count并非最新的count// const increment = useCallback(function foo() {//   console.log("increment");//   setCount(count + 1);// }, []);// 做法二:利用useRef,在组件多次渲染时,返回同一个值const countRef = useRef();countRef.current = count;const increment = useCallback(function foo() {console.log("increment");setCount(countRef.current + 1);},[]);
    

相关文章:

【前端知识】React 基础巩固(四十四)——其他Hooks(useContext、useReducer、useCallback)

React 基础巩固(四十四)——其他Hooks&#xff08;useContext、useReducer、useCallback&#xff09; 一、useContext的使用 在类组件开发时&#xff0c;我们通过 类名.contextType MyContext的方式&#xff0c;在类中获取context&#xff0c;多个Context或者在函数式组件中…...

华为云hcip核心知识笔记(数据库服务规划)

华为云hcip核心知识笔记&#xff08;数据库服务规划&#xff09; 1.云数据接库优势 1.1云数据库优点有&#xff1a; 易用性强&#xff1a;能欧快速部署和运行 高扩展&#xff1a;开放式架构和云计算存储分离 低成本&#xff1a;按需使用&#xff0c;成本更加低廉 2.云数据库r…...

【有趣的】关于Map的一些小测试

Map在代码中用到得非常多&#xff0c;它是无序的、key-value结构的&#xff0c;其读取会非常快。 今天看了个小文章Map判空 、空字符串、空key值等各种判断方法&#xff0c;你都掌握了吗&#xff1f;便自己也玩一下。 一、判空 因为对象已经new出来了&#xff0c;所以map指向的…...

【MATLAB第63期】基于MATLAB的改进敏感性分析方法IPCC,拥挤距离与皮尔逊系数法结合实现回归与分类预测

【MATLAB第63期】基于MATLAB的改进敏感性分析方法IPCC&#xff0c;拥挤距离与皮尔逊系数法结合实现回归与分类预测 思路 考虑拥挤距离指标与PCC皮尔逊相关系数法相结合&#xff0c;对回归或分类数据进行降维&#xff0c;通过SVM支持向量机交叉验证得到平均指标&#xff0c;来…...

AI 绘画Stable Diffusion 研究(二)sd模型ControlNet1.1 介绍与安装

部署包作者:秋葉aaaki 免责声明: 本安装包及启动器免费提供 无任何盈利目的 大家好&#xff0c;我是风雨无阻。 众所周知&#xff0c;StableDiffusion 是非常强大的AI绘图工具&#xff0c;需要详细了解StableDiffusion的朋友&#xff0c;可查看我之前的这篇文章&#xff1a; …...

接口参数设计原则

1. 不能太动态. 不相信客户端的原则 例如传递 filterFields , 推送一个表的某些字段给上游. 2. 可以服务端提供一些封装. 这个封装可以是写死的组合, 也可以是后端配置的. 最好的是 代码里的领域类bean 1,1对应一个名称. 可以是 classReference. 运营态有很多字段是给用户看的…...

网络安全防护利器:SK5代理与IP代理的技术对比

一、IP代理与SK5代理技术简介 IP代理&#xff1a; IP代理是一种通过中间服务器转发网络请求的技术。用户通过向代理服务器发出请求&#xff0c;代理服务器转发请求至目标服务器&#xff0c;然后将目标服务器的响应返回给用户。主要功能包括隐藏真实IP地址、绕过地理限制和IP封锁…...

IDEA删除本地git仓库、创建本地git仓库、关联其他仓库并上传

IDEA删除本地git仓库、创建本地git仓库、关联其他仓库并上传 删除本地Git仓库 创建本地Git仓库 关联其他仓库并上传 要在IntelliJ IDEA中删除本地Git仓库并创建新的本地Git仓库&#xff0c;以及关联其他仓库并上传&#xff0c;请按照以下步骤进行操作&#xff1a; 删除本地G…...

JavaEE简单示例——在使用Tomcat的时候可能出现的一些报错

简单介绍&#xff1a; 在我们之前使用Tomcat的时候&#xff0c;经常会出现在启动的时候因为一些报错导致项目无法正常的启动&#xff0c;我们就对一些比较常见的报错来看一下可能导致的原因&#xff0c;以及出现报错之后如何去解决。 严重: Failed to initialize end point a…...

webrtc的线程模型

目录 线程的声明 线程创建过程 向线程中投递消息 从消息队列中取消息的具体实现 处理线程消息 webrtc线程模块的实现逻辑在 rtc_base\thread.h 文件中 比如想创建一个线程&#xff1a; //声明要创建的线程指针&#xff0c;通过智能指针管理 std::unique_ptr<rtc::Thr…...

数据库备份还原-mysqldump、mydumper、xtrabackup、压缩

目录 数据库备份&#xff0c;数据库为school&#xff0c;素材如下 一、创建student和score表 二、为student表和score表增加记录 三、练习题 数据库备份&#xff0c;数据库为school&#xff0c;素材如下 一、创建student和score表 CREATE TABLE student ( id INT(10) NOT…...

【黑马程序员前端】JavaScript入门到精通--20230801

B站链接 理论 HTML相关知识【黑马程序员前端】 https://blog.csdn.net/m0_48964052/article/details/125951658 CSS相关知识【黑马程序员前端】 https://blog.csdn.net/m0_48964052/article/details/125951788 黑马程序员——JavaScript基础1&#xff08;初识 JavaS…...

100道Java多线程面试题(上)

线程创建方式&#xff1f; 线程有哪些基本状态? 如何停止一个正在运行的线程&#xff1f; 有三个线程T1,T2,T3,如何保证顺序执行&#xff1f; 在线程中你怎么处理不可控制异常&#xff1f; 如何创建线程池&#xff1f; 以下情况如何使用线程池&#xff1f;高并发、任务时间短;…...

web开发中的安全和防御入门——csp (content-security-policy内容安全策略)

偶然碰到iframe跨域加载被拒绝的问题&#xff0c;原因是父页面默认不允许加载跨域的子页面&#xff0c;也就是的content-security-policy中没有设置允许跨域加载。 简单地说&#xff0c;content-security-policy能限制页面允许和不允许加载的所有资源&#xff0c;常见的包括&a…...

定了!全国2023下半年软考(高级、中级、初级)报名时间汇总

截止到2023年8月2日&#xff0c;有以下地区公布了软考报名时间&#xff1a; 安徽软考2023下半年报名时间&#xff1a;8月15日9:00至8月21日16:00 黑龙江软考2023下半年报名时间&#xff1a;8月16日至8月22日 甘肃软考2023下半年报名时间&#xff1a;8月28日9:00至9月6日18:00…...

Linux下安装配置Redis

文章目录 安装依赖库上传安装包并解压 启动默认启动指定配置启动开机自启 安装 依赖库 Redis是基于C语言编写的&#xff0c;因此首先需要安装Redis所需要的gcc依赖&#xff1a; yum install -y gcc tcl上传安装包并解压 将Redis安装包上传到服务器的任意目录&#xff0c;例…...

深度学习(33)——CycleGAN(2)

深度学习&#xff08;33&#xff09;——CycleGAN&#xff08;2&#xff09; 完整项目在在这里&#xff1a;欢迎造访 文章目录 深度学习&#xff08;33&#xff09;——CycleGAN&#xff08;2&#xff09;1. Generator2. Discriminator3. fake pool4. loss定义5. 模型参数量6…...

WeakMap and WeakSet(弱映射和弱集合)

在垃圾回收中了解JavaScript 引擎在值“可达”和可能被使用时会将其保持在内存中 let john { name: "John" }; // 该对象能被访问&#xff0c;john 是它的引用 // 覆盖引用 john null; // 该对象将会被从内存中清除通常&#xff0c;当对象、数组之类的数据结构在内…...

【Vue3基础】组件保持存活、异步加载组件

一、组件保持存活 1、需求描述 点击按钮跳转到其他组件后&#xff0c;原组件不会被销毁 2、知识整理 1&#xff09;组件生命周期 创建期&#xff1a;beforeCreate、created 挂载期&#xff1a;beforeMount、mounted 更新期&#xff1a;beforeUpdate、updated 销毁期&am…...

在 3ds Max 中使用相机映射将静止图像转换为实时素材

推荐&#xff1a; NSDT场景编辑器 助你快速搭建可二次开发的3D应用场景 1. 在 Photoshop 中准备图像 步骤 1 这是我将在教程中使用的静止图像。 这是我的静态相机纸箱的快照。 静止图像 步骤 2 打开 Photoshop。将图像导入 Photoshop。 打开 Photoshop 步骤 3 单击套索工…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...