React强大且灵活hooks库——ahooks入门实践之高级类hook(advanced)详解

什么是 ahooks?

ahooks 是一个 React Hooks 库,提供了大量实用的自定义 hooks,帮助开发者更高效地构建 React 应用。其中高级类 hooks 是 ahooks 的一个重要分类,专门用于处理一些高级场景,如受控值、事件发射器、性能优化等。

安装 ahooks

npm install ahooks

高级类 hooks 详解

useControllableValue – 受控值

useControllableValue 用于处理受控和非受控组件的值管理。

import React, { useState } from "react";
import { useControllableValue } from "ahooks";
import { Card, Input, Button, Switch } from "antd";const UseControllableValueExample = () => {const [controlled, setControlled] = useState(false);const [value, setValue] = useControllableValue({value: controlled ? "受控值" : undefined,defaultValue: "默认值",onChange: (val) => {console.log("值变化:", val);},});return (<Card title="useControllableValue 受控值"><div style={{ marginBottom: 16 }}><p><strong>当前值:</strong> {value}</p><p><strong>模式:</strong> {controlled ? "受控" : "非受控"}</p></div><div style={{ marginBottom: 16 }}><Inputvalue={value}onChange={(e) => setValue(e.target.value)}placeholder="输入内容"style={{ marginBottom: 8 }}/><Switchchecked={controlled}onChange={setControlled}checkedChildren="受控"unCheckedChildren="非受控"/></div><Button onClick={() => setValue("重置值")}>重置</Button></Card>);
};

useCreation – 创建值

useCreation 用于创建值,类似于 useMemo,但更稳定。

import React, { useState } from "react";
import { useCreation } from "ahooks";
import { Card, Button } from "antd";const UseCreationExample = () => {const [count, setCount] = useState(0);// 使用 useCreation 创建稳定的对象const stableObject = useCreation(() => {return {id: Math.random(),timestamp: Date.now(),};}, []);// 使用 useCreation 创建计算值const expensiveValue = useCreation(() => {console.log("计算昂贵值");return count * 2 + 10;}, [count]);return (<Card title="useCreation 创建值"><div style={{ marginBottom: 16 }}><p><strong>计数:</strong> {count}</p><p><strong>计算值:</strong> {expensiveValue}</p><p><strong>稳定对象 ID:</strong> {stableObject.id}</p><p><strong>稳定对象时间戳:</strong> {stableObject.timestamp}</p></div><Button onClick={() => setCount(count + 1)}>增加计数</Button></Card>);
};

useEventEmitter – 事件发射器

useEventEmitter 用于创建事件发射器,实现组件间通信。

import React, { useRef } from "react";
import { useEventEmitter } from "ahooks";
import { Card, Button, Input } from "antd";const UseEventEmitterExample = () => {const eventEmitter = useEventEmitter();const handleEmit = () => {eventEmitter.emit();};return (<Card title="useEventEmitter 事件发射器"><div style={{ marginBottom: 16 }}><p>点击按钮发射事件,输入框会自动获得焦点</p></div><Button onClick={handleEmit} style={{ marginBottom: 16 }}>发射事件</Button><InputBox eventEmitter={eventEmitter} /></Card>);
};// 输入框组件
const InputBox = ({ eventEmitter }) => {const inputRef = useRef(null);eventEmitter.useSubscription(() => {inputRef.current?.focus();});return (<Inputref={inputRef}placeholder="输入框会自动获得焦点"style={{ width: "100%" }}/>);
};export default UseEventEmitterExample;

useIsomorphicLayoutEffect – 同构布局副作用

useIsomorphicLayoutEffect 在服务端渲染时使用 useEffect,在客户端使用 useLayoutEffect

import React, { useState, useRef } from "react";
import { useIsomorphicLayoutEffect } from "ahooks";
import { Card, Button } from "antd";const UseIsomorphicLayoutEffectExample = () => {const [count, setCount] = useState(0);const ref = useRef(null);useIsomorphicLayoutEffect(() => {if (ref.current) {// 在布局更新前同步执行ref.current.style.backgroundColor =count % 2 === 0 ? "#f0f0f0" : "#e6f7ff";}}, [count]);return (<Card title="useIsomorphicLayoutEffect 同构布局副作用"><div style={{ marginBottom: 16 }}><p><strong>计数:</strong> {count}</p></div><divref={ref}style={{padding: 16,border: "1px solid #d9d9d9",borderRadius: 4,transition: "background-color 0.3s",}}>这个div的背景色会在布局更新前同步改变</div><Button onClick={() => setCount(count + 1)} style={{ marginTop: 16 }}>切换背景色</Button></Card>);
};

useLatest – 最新值

useLatest 返回一个 ref,始终指向最新的值。

import React, { useState, useEffect } from "react";
import { useLatest } from "ahooks";
import { Card, Button } from "antd";const UseLatestExample = () => {const [count, setCount] = useState(0);const latestCount = useLatest(count);useEffect(() => {const timer = setInterval(() => {console.log("当前值:", count);console.log("最新值:", latestCount.current);}, 1000);return () => clearInterval(timer);}, []);return (<Card title="useLatest 最新值"><div style={{ marginBottom: 16 }}><p><strong>当前值:</strong> {count}</p><p><strong>最新值引用:</strong> {latestCount.current}</p><p style={{ fontSize: "12px", color: "#666" }}>每秒在控制台输出当前值和最新值引用</p></div><Button onClick={() => setCount(count + 1)}>增加计数</Button></Card>);
};

useMemoizedFn – 记忆化函数

useMemoizedFn 用于创建记忆化的函数,避免不必要的重新渲染。

import React, { useState } from "react";
import { useMemoizedFn } from "ahooks";
import { Card, Button } from "antd";const UseMemoizedFnExample = () => {const [count, setCount] = useState(0);const [renderCount, setRenderCount] = useState(0);// 使用 useMemoizedFn 创建稳定的函数const handleClick = useMemoizedFn(() => {setCount(count + 1);console.log("点击处理函数执行");});// 每次渲染都会创建新函数const handleClickNormal = () => {setCount(count + 1);console.log("普通函数执行");};// 强制重新渲染const forceRender = () => {setRenderCount(renderCount + 1);};return (<Card title="useMemoizedFn 记忆化函数"><div style={{ marginBottom: 16 }}><p><strong>计数:</strong> {count}</p><p><strong>渲染次数:</strong> {renderCount}</p></div><div style={{ marginBottom: 16 }}><Button onClick={handleClick} style={{ marginRight: 8 }}>记忆化函数</Button><Button onClick={handleClickNormal} style={{ marginRight: 8 }}>普通函数</Button><Button onClick={forceRender}>强制重新渲染</Button></div><p style={{ fontSize: "12px", color: "#666" }}>记忆化函数在重新渲染时保持稳定,普通函数每次都会重新创建</p></Card>);
};

useReactive – 响应式状态

useReactive 用于创建响应式状态对象。

import React from "react";
import { useReactive } from "ahooks";
import { Card, Button, Input } from "antd";const UseReactiveExample = () => {const state = useReactive({user: {name: "张三",age: 25,},count: 0,list: [1, 2, 3],});const handleUpdateName = () => {state.user.name = "李四";};const handleUpdateAge = () => {state.user.age += 1;};const handleAddCount = () => {state.count += 1;};const handleAddToList = () => {state.list.push(state.list.length + 1);};return (<Card title="useReactive 响应式状态"><div style={{ marginBottom: 16 }}><p><strong>用户名:</strong> {state.user.name}</p><p><strong>年龄:</strong> {state.user.age}</p><p><strong>计数:</strong> {state.count}</p><p><strong>列表:</strong> {state.list.join(", ")}</p></div><div style={{ marginBottom: 16 }}><Inputvalue={state.user.name}onChange={(e) => (state.user.name = e.target.value)}placeholder="输入用户名"style={{ marginBottom: 8 }}/></div><div><Button onClick={handleUpdateName} style={{ marginRight: 8 }}>更新姓名</Button><Button onClick={handleUpdateAge} style={{ marginRight: 8 }}>增加年龄</Button><Button onClick={handleAddCount} style={{ marginRight: 8 }}>增加计数</Button><Button onClick={handleAddToList}>添加列表项</Button></div></Card>);
};

高级类 hooks 速查表

Hook 名称用途描述
useControllableValue受控值处理受控和非受控组件的值管理
useCreation创建值创建稳定的值,类似于 useMemo
useEventEmitter事件发射器创建事件发射器,实现组件间通信
useIsomorphicLayoutEffect同构布局副作用在服务端和客户端使用不同的副作用
useLatest最新值返回一个始终指向最新值的 ref
useMemoizedFn记忆化函数创建记忆化的函数,避免不必要的重新渲染
useReactive响应式状态创建响应式状态对象

 React强大且灵活hooks库——ahooks入门实践之高级类hook(advanced)详解 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿动态资讯

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

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

相关文章

计算机网络——数据链路层(25王道最新版)

数据链路层前言数据链路层的功能封装成帧&#xff08;组帧&#xff09;字符计数法字节填充法零比特填充法违规编码法小节差错控制检错编码奇偶校验码CRC校验码&#xff08;循环冗余校验码&#xff09;基本思想如何构造如何检错纠错纠错编码海明校验码设计思路求解步骤&#xff…

【PTA数据结构 | C语言版】字符串替换算法

本专栏持续输出数据结构题目集&#xff0c;欢迎订阅。 文章目录题目代码题目 请编写程序&#xff0c;将给定主串 s 中的子串 sub_s 替换成另一个给定字符串 t&#xff0c;再输出替换后的主串 s。 输入格式&#xff1a; 输入给出 3 个非空字符串&#xff0c;依次为&#xff1a…

事物生效,订单类内部更新订单

代码如下以下代码1不生效&#xff0c;2生效解决方案1&#xff0c;外层方法加注解&#xff0c;内层不加2&#xff0c;不要拆分方法&#xff0c;把更新订单操作放在带事物的大方法中3&#xff0c;拆方法&#xff08;内部&#xff09;&#xff0c;注入自己&#xff0c;用代理对象调…

非对称加密:RSA

文章目录 非对称加密:RSA 1、RSA 加解密 2、RSA 生成密钥对(公钥、私钥)、加解密 参考资料 非对称加密:RSA 1、RSA 加解密 <!-- RSA --><!-- 引入jsencrypt库 --><script src="https://cdn.bootcdn.net/ajax/libs/jsencrypt/3.3.2/jsencrypt.min.js&q…

MongoDB 数据库 启用访问控制

0. 最近服务器安装了 MongoDB 被勒索了 测试服务器安装了 MongoDB 等&#xff0c;开放了 27017 对所有 ip。 哈哈哈哈哈哈&#xff0c;问就是有点犯懒&#xff0c;之前都是只允许自己的 ip。 好家伙&#xff0c;然后没过几个小时&#xff0c;数据库集合被清空&#xff0c;只留…

【Unity Sprite属性拓展】

Unity Inspector 精灵图预览为 Unity 中的 Sprite 类型属性提供了​​增强版的 Inspector 显示​​&#xff0c;在保留标准精灵选择功能的基础上&#xff0c;添加了大型预览图和精灵名称显示功能代码 using UnityEngine; using UnityEditor;// 1️⃣ 告诉 Unity&#xff1a;所有…

细菌实验入门:浓度测定与菌种鉴定技术详解

在微生物实验中&#xff0c;细菌浓度的精准测定和菌种的准确鉴定是两项基础且核心的操作。本文将详细介绍相关技术的原理、操作步骤及注意事项&#xff0c;为新手提供系统性指导。一、细菌浓度测定方法1. 光密度法&#xff08;OD600&#xff09;&#xff1a;快速定量的首选原理…

GaussDB 数据库架构师修炼(一)数据库容量规划

1、容量规划的定义GaussDB容量规划是指根据客户业务系统的负载需求或历史运行数据&#xff0c;进行合理规划GaussDB的计算、存储和网络资源配置&#xff0c;以满足业务系统正常使用和未来若干年负载增长诉求的过程。2、容量规划活动主要步骤需求收集调研生产系统的业务特征&…

hashMap原理(一)

概念HashMap是java中一种非常常用的基于哈希表的数据结构&#xff0c;允许o(1)的时间复杂度进行元素插入&#xff0c;查找&#xff0c;和删除。它通过”键-值“ 对的方式存储数据。总的来说&#xff1a;HashMap的底层原理&#xff1a;数组链表红黑树&#xff08;jdk1.8之后还涉…

Ubuntu24 辅助系统-屏幕键盘的back按键在网页文本框删除不正常的问题解决方法

Ubuntu24 辅助系统-屏幕键盘的back按键异常 问题描述ubuntu24这个屏幕键盘&#xff0c;只有在网页的搜索框或者文本框&#xff0c;比如百度首页的搜索框&#xff0c;留言的文本框&#xff0c;才会出现点击back按钮的时候&#xff0c;出现了先选中当前这个字符&#xff0c;删除此…

自然语言指令驱动的工业机器人协同学习系统:大语言模型如何重塑智能体协作范式

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

web:js的switch语句

在js中,switch语句是一种用于根据不同的条件执行不同代码块的控制流语句。它类似于多个if...else if...else语句,但结构更清晰,特别是在有多个条件分支的情况下。 基本语法 switch (expression) {case value1:// 当expression的值等于value1时执行这里的代码break;case va…

为何说分布式 AI 推理已成为下一代计算方式

2024 年&#xff0c;我们见证了人工智能创新的空前爆发。AI 的快速发展令很多人惊叹&#xff0c;为了训练更先进的大语言模型&#xff08;LLM&#xff09;&#xff0c;科技巨头争相获取强大的 GPU。如今&#xff0c;AI 正在无缝融入我们世界的每个角落。在众多新兴 AI 公司、模…

阿里云 RabbitMQ 可观测性最佳实践

阿里云 RabbitMQ 阿里云 RabbitMQ 是一款高性能、高可靠的消息中间件&#xff0c;支持多种消息协议和丰富的功能特性。它提供消息队列功能&#xff0c;能够实现应用间的消息解耦和异步通信&#xff0c;提升系统扩展性和稳定性。其支持多种消息持久化策略&#xff0c;确保消息不…

vue-router 导航式编程 参数的设置

主要是想记录一下this.$router.push、replace、go等方法的参数如何设置。字符串路径router.push(/home)直接使用字符串&#xff08;或模板字符串&#xff09;路径&#xff0c;可跳转到相应的URL路径。对象式路径路径也可以是一个对象&#xff0c;对象里以key:value的形式表示UR…

Swift实现股票图:从基础到高级

目录一、核心实现方案1. 原生方案&#xff1a;使用 Core Graphics 绘制2. 使用第三方库&#xff1a;Charts3. 跨平台方案&#xff1a;使用 SwiftUI Canvas二、技术指标实现1. 移动平均线 (MA)2. 布林带 (Bollinger Bands)3. MACD (Moving Average Convergence Divergence)三、…

【unitrix】 6.4 数特征(number.rs)

一、源码 这段代码定义了一个名为Number的trait&#xff08;特质&#xff09;以及它的实现。 use crate::sealed::Sealed; use crate::number::{V, BaseNumber, TNumber};/// 数值的统一标记特质 /// 可以是编译时类型化数字(TNumber)或运行时变量(V<T>) pub trait Numbe…

AI治AI:大语言模型自检新法

“以火攻火”的思路解决大语言模型(LLMs)“幻觉”问题 虚构是由于与提示无关的内部因素而不可预测地从 LLM 中出现的幻觉。作者专注于衡量 LLM 对提示响应的不确定性,使用高不确定性表示虚构的假设。他们通过计算一个称为熵的量来估计这种不确定性**,熵可以被认为是模型生…

ESLint 配置错误:ReferenceError: prettier is not defined 解决方案

问题描述在使用 pnpm lint 运行 ESLint 时&#xff0c;出现以下错误&#xff1a;Oops! Something went wrong! :( ESLint: 9.31.0 ReferenceError: prettier is not defined该错误导致 ESLint 无法正确执行代码格式检查&#xff0c;但 不会影响项目的实际运行&#xff08;如 pn…

数据结构--准备知识

一.算法效率算法效率分为两种&#xff1a;第一种为时间效率&#xff0c;第二种为空间效率。时间效率称为时间复杂度&#xff0c;空间效率称为空间复杂度。时间复杂主要衡量一个算法的运行速度&#xff0c;空间复杂度主要衡量一个算法所需的 额外的空间&#xff08;现在不需要特…