【前端知识】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);},[]);
    

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

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

相关文章

手机设置全局代理ip步骤

在互联网时代&#xff0c;隐私和安全问题备受关注。使用全局代理能够帮助我们保护个人信息&#xff0c;突破地理限制&#xff0c;并提高网络速度。但是&#xff0c;你是否对全局代理的安全性存有疑虑&#xff1f;而且&#xff0c;如何在手机上设置全局代理呢&#xff1f;今天就…

用LangChain开源框架实现知识机器人

前言 Large Language Models (LLMs)在2020年OpenAI 的 GPT-3 的发布而进入世界舞台 。从那时起&#xff0c;他们稳步增长进入公众视野。 众所周知 OpenAI 的 API 无法联网&#xff0c;所以大家如果想通过它的API实现联网搜索并给出回答、总结 PDF 文档、基于某个 Youtube 视频…

优维低代码实践:Context / State

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

阿里云 MSE + ZadigX ,无门槛实现云原生全链路灰度发布

作者&#xff1a;ZadigX 企业发布现状痛点 目前企业在选择和实施发布策略时面临以下困境&#xff1a; 1. 缺乏云原生能力&#xff1a; 由于从传统部署转变为云原生模式后&#xff0c;技术架构改造需要具备相关能力的人才。这使得企业在发布策略方面难以入手。 2. 缺乏自动化…

U盘删除的文件怎么找回?4个简单方法分享!

“在u盘里不小心删除的文件到底还能不能找回来呀&#xff1f;真的好着急啊&#xff01;这个u盘对我来说真的很重要&#xff0c;怎么恢复里面的数据呢&#xff1f;请各位大佬帮帮我吧&#xff01;” 作为一个便捷的存储工具&#xff0c;u盘逐渐获得大众的青睐。在互联网时代&…

《练习100》36~40

题目36 # 对10个数排序my_list [2,2,1,1,3,67,43,22,55,10,11]print(my_list) my_list.sort() print(my_list)题目37 # 求一个3*3的矩阵对角线元素之和 # 主对角线&#xff1a; 00 11 22 # 副对角线&#xff1a; 02 11 20def get_diagonal_sum(matrix):matsize len(matrix)…

微服务性能分析工具 Pyroscope 初体验

Go 自带接口性能分析工具 pprof&#xff0c;较为常用的有以下 4 种分析&#xff1a; CPU Profiling: CPU 分析&#xff0c;按照一定的频率采集所监听的应用程序 CPU&#xff08;含寄存器&#xff09;的使用情况&#xff0c;可确定应用程序在主动消耗 CPU 周期时花费时间的位置…

计算机毕设 深度学习手势识别 - yolo python opencv cnn 机器视觉

文章目录 0 前言1 课题背景2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存 5 模型训练5.1 修…

Doccano工具安装教程/文本标注工具/文本标注自己的项目/NLP分词器工具/自然语言处理必备工具/如何使用文本标注工具

这篇文章是专门的安装教程&#xff0c;后续的项目创建&#xff0c;如何使用&#xff0c;以及代码部分可以参考这篇文章&#xff1a; NER实战&#xff1a;(NLP实战/命名实体识别/文本标注/Doccano工具使用/关键信息抽取/Token分类/源码解读/代码逐行解读)_会害羞的杨卓越的博客-…

SO_KEEPALIVE、TCP_KEEPIDLE、TCP_KEEPINTVL、保活包

SO_KEEPALIVE SO_KEEPALIVE 是一个套接字选项&#xff0c;用于设置是否启用 keepalive 机制。在这段代码中没有涉及到 SO_KEEPALIVE 选项的设置。 当 SO_KEEPALIVE 被设置为非零值时&#xff0c;表示启用 keepalive 机制。keepalive 是一种用于检测连接是否仍然有效的机制。通…

SVN学习

SVN学习 以下总结是看了一个b站up主的视频总结出来的。 1. 简介 SVN是代码版本管理工具&#xff0c;它能记住每次的修改、查看所有修改记录、恢复到任何历史版本和恢复已经删除的文件。 SVN比起Git的好处就是使用简单&#xff0c;上手快&#xff1b;具备目录级权限控制&…

【LeetCode每日一题】——1572.矩阵对角线元素的和

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 矩阵 二【题目难度】 简单 三【题目编号】 1572.矩阵对角线元素的和 四【题目描述】 给你一…

交换机VLAN技术和实验(eNSP)

目录 一&#xff0c;交换机的演变 1.1&#xff0c;最小网络单元 1.2&#xff0c;中继器&#xff08;物理层&#xff09; 1.3&#xff0c;集线器&#xff08;物理层&#xff09; 1.4&#xff0c;网桥&#xff08;数据链路层&#xff09; 二&#xff0c;交换机的工作行为 2.…

【计算机视觉中的 GAN 】如何稳定GAN训练(3)

一、说明 在上一篇文章中&#xff0c;我们达到了理解未配对图像到图像翻译的地步。尽管如此&#xff0c;在实现自己的超酷深度GAN模型之前&#xff0c;您必须了解一些非常重要的概念。如本文所提的GAN模型新成员的引入&#xff1a;Wasserstein distance&#xff0c;boundary eq…

AI 绘画Stable Diffusion 研究(一)sd整合包v4.2 版本安装说明

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

【机器学习】Feature scaling and Learning Rate (Multi-variable)

Feature scaling and Learning Rate 1、数据集2、学习率2.1 α \alpha α 9.9e-72.2 α \alpha α 9e-72.3 α \alpha α 1e-7 3、特征缩放3.1 特征缩放的原因3.2 Z-score 归一化3.3 预测3.4 损失等值线 导入所需的库 import numpy as np np.set_printoptions(precision…

sqlserver 使用SQLOLEDB 远程数据库同步数据

exec sp_addlinkedserver remote_server, , SQLOLEDB, ip exec sp_addlinkedsrvlogin remote_server, false,null, 账号, 密码 --查询方式 select * from remote_server.数据库名.dbo.表名 --不再使用时删除链接服务器 exec sp_dropserver remote_server, droplogins…

Oracle免费在线编程:Oracle APEX

前提&#xff1a; 注意&#xff1a;你要有个梯子才能更稳定的访问。 不需要安装Oracle&#xff0c;但是需要注册。&#xff08;还算方便的&#xff09; 注册&登录过程 进入Oracle APEX官网&#xff0c;我们选择免费的APEX工作区即可&#xff0c;点击“免费注册”。在注册…

DASCTF 2023 0X401七月暑期挑战赛web复现

目录 <1> Web (1) EzFlask(python原型链污染&flask-pin) (2) MyPicDisk(xpath注入&文件名注入) (3) ez_cms(pearcmd文件包含) (4) ez_py(django框架 session处pickle反序列化) <1> Web (1) EzFlask(python原型链污染&flask-pin) 进入题目 得到源…

软件设计师(五)软件工程基础知识

一、软件工程概述 软件开发和维护过程中所遇到的各种问题称为“软件危机”。 软件工程是指应用计算机科学、数学及管理科学等原理&#xff0c;以工程化的原则和方法来解决软件问题的工程&#xff0c;其目的是提高软件生产率、提高软件质量、降低软件成本。 #mermaid-svg-h3j6K…