React强大且灵活hooks库——ahooks入门实践之副作用类hook(effect)详解

什么是 ahooks?

ahooks 是一个 React Hooks 库,提供了大量实用的自定义 hooks,帮助开发者更高效地构建 React 应用。其中副作用类 hooks 是 ahooks 的一个重要分类,专门用于处理各种副作用操作,如定时器、防抖、节流等。

安装 ahooks

npm install ahooks

副作用类 hooks 详解

useUpdateEffect – 更新时执行副作用

useUpdateEffect 在依赖项更新时执行副作用,跳过首次执行。

import React, { useState } from "react";
import { useUpdateEffect } from "ahooks";
import { Button, Card } from "antd";const UseUpdateEffectExample = () => {const [count, setCount] = useState(0);const [updateCount, setUpdateCount] = useState(0);useUpdateEffect(() => {console.log("依赖项更新,执行副作用");setUpdateCount((prev) => prev + 1);}, [count]);return (<Card title="useUpdateEffect 更新时执行副作用"><div style={{ marginBottom: 16 }}><p><strong>计数:</strong> {count}</p><p><strong>更新次数:</strong> {updateCount}</p></div><Button onClick={() => setCount(count + 1)}>增加计数</Button></Card>);
};

useUpdateLayoutEffect – 更新时执行布局副作用

useUpdateLayoutEffect 在依赖项更新时执行布局副作用,跳过首次执行。

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

useAsyncEffect – 异步副作用

useAsyncEffect 用于处理异步副作用操作。

import React, { useState } from "react";
import { useAsyncEffect } from "ahooks";
import { Button, Card } from "antd";const UseAsyncEffectExample = () => {const [data, setData] = useState(null);const [loading, setLoading] = useState(false);useAsyncEffect(async () => {setLoading(true);try {// 模拟异步请求await new Promise((resolve) => setTimeout(resolve, 1000));setData("异步数据加载完成");} catch (error) {setData("加载失败");} finally {setLoading(false);}}, []);return (<Card title="useAsyncEffect 异步副作用"><div style={{ marginBottom: 16 }}><p><strong>状态:</strong> {loading ? "加载中..." : data}</p></div><Button disabled={loading}>组件挂载时自动加载数据</Button></Card>);
};

useDebounceEffect – 防抖副作用

useDebounceEffect 创建防抖的副作用,延迟执行。

import React, { useState } from "react";
import { useDebounceEffect } from "ahooks";
import { Input, Card } from "antd";const UseDebounceEffectExample = () => {const [value, setValue] = useState("");const [debouncedValue, setDebouncedValue] = useState("");useDebounceEffect(() => {setDebouncedValue(value);console.log("防抖后的值:", value);},[value],{ wait: 500 });return (<Card title="useDebounceEffect 防抖副作用"><div style={{ marginBottom: 16 }}><Inputplaceholder="输入内容(500ms 防抖)"value={value}onChange={(e) => setValue(e.target.value)}style={{ marginBottom: 8 }}/><p><strong>实时值:</strong> {value}</p><p><strong>防抖值:</strong> {debouncedValue}</p></div></Card>);
};

useDebounceFn – 防抖函数

useDebounceFn 创建防抖函数。

import React, { useState } from "react";
import { useDebounceFn } from "ahooks";
import { Button, Card } from "antd";const UseDebounceFnExample = () => {const [count, setCount] = useState(0);const { run } = useDebounceFn(() => {setCount((prev) => prev + 1);},{ wait: 1000 });return (<Card title="useDebounceFn 防抖函数"><div style={{ marginBottom: 16 }}><p><strong>计数:</strong> {count}</p><p style={{ fontSize: "12px", color: "#666" }}>快速点击按钮,只有最后一次点击会在1秒后生效</p></div><Button onClick={run}>防抖增加计数</Button></Card>);
};

useThrottleFn – 节流函数

useThrottleFn 创建节流函数。

import React, { useState } from "react";
import { useThrottleFn } from "ahooks";
import { Button, Card } from "antd";const UseThrottleFnExample = () => {const [count, setCount] = useState(0);const { run } = useThrottleFn(() => {setCount((prev) => prev + 1);},{ wait: 1000 });return (<Card title="useThrottleFn 节流函数"><div style={{ marginBottom: 16 }}><p><strong>计数:</strong> {count}</p><p style={{ fontSize: "12px", color: "#666" }}>快速点击按钮,每秒最多执行一次</p></div><Button onClick={run}>节流增加计数</Button></Card>);
};

useThrottleEffect – 节流副作用

useThrottleEffect 创建节流的副作用。

import React, { useState } from "react";
import { useThrottleEffect } from "ahooks";
import { Input, Card } from "antd";const UseThrottleEffectExample = () => {const [value, setValue] = useState("");const [throttledValue, setThrottledValue] = useState("");useThrottleEffect(() => {setThrottledValue(value);console.log("节流后的值:", value);},[value],{ wait: 1000 });return (<Card title="useThrottleEffect 节流副作用"><div style={{ marginBottom: 16 }}><Inputplaceholder="输入内容(1000ms 节流)"value={value}onChange={(e) => setValue(e.target.value)}style={{ marginBottom: 8 }}/><p><strong>实时值:</strong> {value}</p><p><strong>节流值:</strong> {throttledValue}</p></div></Card>);
};

useDeepCompareEffect – 深度比较副作用

useDeepCompareEffect 使用深度比较来决定是否执行副作用。

import React, { useState } from "react";
import { useDeepCompareEffect } from "ahooks";
import { Button, Card } from "antd";const UseDeepCompareEffectExample = () => {const [obj, setObj] = useState({ name: "张三", age: 25 });const [count, setCount] = useState(0);useDeepCompareEffect(() => {console.log("对象深度比较后发生变化:", obj);setCount((prev) => prev + 1);}, [obj]);return (<Card title="useDeepCompareEffect 深度比较副作用"><div style={{ marginBottom: 16 }}><p><strong>对象:</strong> {JSON.stringify(obj)}</p><p><strong>执行次数:</strong> {count}</p></div><div><ButtononClick={() => setObj({ name: "张三", age: 25 })}style={{ marginRight: 8 }}>设置相同对象(浅比较会触发,深度比较不会)</Button><Button onClick={() => setObj({ name: "李四", age: 30 })}>设置不同对象</Button></div></Card>);
};

useDeepCompareLayoutEffect – 深度比较布局副作用

useDeepCompareLayoutEffect 使用深度比较来决定是否执行布局副作用。

import React, { useState, useRef } from "react";
import { useDeepCompareLayoutEffect } from "ahooks";
import { Button, Card } from "antd";const UseDeepCompareLayoutEffectExample = () => {const [config, setConfig] = useState({ width: 100, height: 100 });const divRef = useRef(null);useDeepCompareLayoutEffect(() => {if (divRef.current) {divRef.current.style.width = `${config.width}px`;divRef.current.style.height = `${config.height}px`;}}, [config]);return (<Card title="useDeepCompareLayoutEffect 深度比较布局副作用"><div style={{ marginBottom: 16 }}><divref={divRef}style={{backgroundColor: "#1890ff",transition: "all 0.3s",}}/><p><strong>配置:</strong> {JSON.stringify(config)}</p></div><div><ButtononClick={() => setConfig({ width: 100, height: 100 })}style={{ marginRight: 8 }}>设置相同配置</Button><Button onClick={() => setConfig({ width: 200, height: 150 })}>设置不同配置</Button></div></Card>);
};

useInterval – 定时器

useInterval 创建定时器。

import React, { useState } from "react";
import { useInterval } from "ahooks";
import { Button, Card } from "antd";const UseIntervalExample = () => {const [count, setCount] = useState(0);const [delay, setDelay] = useState(1000);useInterval(() => {setCount((prev) => prev + 1);}, delay);return (<Card title="useInterval 定时器"><div style={{ marginBottom: 16 }}><p><strong>计数:</strong> {count}</p><p><strong>间隔:</strong> {delay}ms</p></div><div><Button onClick={() => setDelay(1000)} style={{ marginRight: 8 }}>1秒间隔</Button><Button onClick={() => setDelay(2000)} style={{ marginRight: 8 }}>2秒间隔</Button><Button onClick={() => setDelay(null)}>停止</Button></div></Card>);
};

useRafInterval – RAF 定时器

useRafInterval 使用 requestAnimationFrame 创建定时器。

import React, { useState } from "react";
import { useRafInterval } from "ahooks";
import { Button, Card } from "antd";const UseRafIntervalExample = () => {const [count, setCount] = useState(0);const [delay, setDelay] = useState(1000);useRafInterval(() => {setCount((prev) => prev + 1);}, delay);return (<Card title="useRafInterval RAF 定时器"><div style={{ marginBottom: 16 }}><p><strong>计数:</strong> {count}</p><p><strong>间隔:</strong> {delay}ms</p><p style={{ fontSize: "12px", color: "#666" }}>使用 requestAnimationFrame,性能更好</p></div><div><Button onClick={() => setDelay(1000)} style={{ marginRight: 8 }}>1秒间隔</Button><Button onClick={() => setDelay(2000)} style={{ marginRight: 8 }}>2秒间隔</Button><Button onClick={() => setDelay(null)}>停止</Button></div></Card>);
};

useTimeout – 延时器

useTimeout 创建延时器。

import React, { useState } from "react";
import { useTimeout } from "ahooks";
import { Button, Card } from "antd";const UseTimeoutExample = () => {const [message, setMessage] = useState("");useTimeout(() => {setMessage("3秒后显示的消息");}, 3000);return (<Card title="useTimeout 延时器"><div style={{ marginBottom: 16 }}><p><strong>消息:</strong> {message || "等待中..."}</p></div><Button disabled>组件挂载3秒后显示消息</Button></Card>);
};

useRafTimeout – RAF 延时器

useRafTimeout 使用 requestAnimationFrame 创建延时器。

import React, { useState } from "react";
import { useRafTimeout } from "ahooks";
import { Button, Card } from "antd";const UseRafTimeoutExample = () => {const [message, setMessage] = useState("");useRafTimeout(() => {setMessage("2秒后显示的消息(RAF)");}, 2000);return (<Card title="useRafTimeout RAF 延时器"><div style={{ marginBottom: 16 }}><p><strong>消息:</strong> {message || "等待中..."}</p><p style={{ fontSize: "12px", color: "#666" }}>使用 requestAnimationFrame,性能更好</p></div><Button disabled>组件挂载2秒后显示消息</Button></Card>);
};

useLockFn – 锁函数

useLockFn 创建锁函数,防止重复执行。

import React, { useState } from "react";
import { useLockFn } from "ahooks";
import { Button, Card } from "antd";const UseLockFnExample = () => {const [loading, setLoading] = useState(false);const [count, setCount] = useState(0);const handleClick = useLockFn(async () => {setLoading(true);// 模拟异步操作await new Promise((resolve) => setTimeout(resolve, 2000));setCount((prev) => prev + 1);setLoading(false);});return (<Card title="useLockFn 锁函数"><div style={{ marginBottom: 16 }}><p><strong>计数:</strong> {count}</p><p><strong>状态:</strong> {loading ? "执行中..." : "空闲"}</p></div><Button onClick={handleClick} loading={loading}>点击执行(2秒内重复点击无效)</Button></Card>);
};

useUpdate – 强制更新

useUpdate 强制组件重新渲染。

import React from "react";
import { useUpdate } from "ahooks";
import { Button, Card } from "antd";const UseUpdateExample = () => {const update = useUpdate();return (<Card title="useUpdate 强制更新"><div style={{ marginBottom: 16 }}><p><strong>渲染时间:</strong> {new Date().toLocaleTimeString()}</p></div><Button onClick={update}>强制重新渲染</Button></Card>);
};

副作用类 hooks 速查表

Hook 名称用途描述
useUpdateEffect更新时执行副作用在依赖项更新时执行,跳过首次执行
useUpdateLayoutEffect更新时执行布局副作用在依赖项更新时执行布局副作用
useAsyncEffect异步副作用处理异步副作用操作
useDebounceEffect防抖副作用创建防抖的副作用,延迟执行
useDebounceFn防抖函数创建防抖函数
useThrottleFn节流函数创建节流函数
useThrottleEffect节流副作用创建节流的副作用
useDeepCompareEffect深度比较副作用使用深度比较决定是否执行副作用
useDeepCompareLayoutEffect深度比较布局副作用使用深度比较决定是否执行布局副作用
useInterval定时器创建定时器
useRafIntervalRAF 定时器使用 requestAnimationFrame 创建定时器
useTimeout延时器创建延时器
useRafTimeoutRAF 延时器使用 requestAnimationFrame 创建延时器
useLockFn锁函数创建锁函数,防止重复执行
useUpdate强制更新强制组件重新渲染

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

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

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

相关文章

SpringBoot一Web Flux、函数式Web请求的使用、和传统注解@Controller + @RequestMapping的区别

一、函数式 Web 在 Spring Boot 中&#xff0c;使用函数式 Web&#xff08;Function-based Web&#xff09;可以通过 RouterFunction 和 HandlerFunction 来定义路由和请求处理逻辑。这种方式与传统的注解驱动的方式不同&#xff0c;它更加简洁&#xff0c;并且适合响应式编程。…

Vue+Cesium快速配置指南

安装必要依赖在项目根目录下运行以下命令安装vue-cesium和cesium&#xff1a;npm install vue-cesium3.1.4 cesium1.84配置Vite在vite.config.js文件中添加以下配置&#xff1a;import { defineConfig } from vite import vue from vitejs/plugin-vue import { resolve } from …

矿业自动化破壁者:EtherCAT转PROFIBUS DP网关的井下实战

在深井钻机的轰鸣、矿石输送带的奔流与通风设备的不息运转中&#xff0c;矿业生产的脉搏强劲跳动。然而&#xff0c;这片创造价值的土地&#xff0c;却为自动化技术的深入设置了严苛的考场&#xff1a;信息孤岛林立&#xff1a; 高效现代的EtherCAT控制系统与井下大量稳定服役的…

SpringBoot+Loki4j+Loki+Grafana搭建轻量级日志系统

文章目录前言一、组件介绍&#xff08;一&#xff09;Loki特点架构适用场景总结&#xff08;二&#xff09;Loki4j特点&#xff08;三&#xff09;Grafana特点适用场景二、组件配置&#xff08;一&#xff09;Loki&#xff08;二&#xff09;Grafana三、项目搭建参考文章前言 …

SpringCloud之Config

SpringCloud之Config 推荐网站&#xff1a;https://www.springcloud.cc/spring-cloud-dalston.html#_spring_cloud_config 1. 什么是 Spring Cloud Config Spring Cloud Config 是 Spring 官方提供的 分布式配置中心 组件&#xff0c;用来 集中管理、动态下发、版本控制 所有微…

探索VB.NET中的贝塞尔Bezier曲线绘制技巧

简介&#xff1a;Bezier曲线是计算机图形学中用于创建平滑曲线的重要工具&#xff0c;广泛应用于图形设计、游戏开发、CAD系统等领域。本文深入探讨了Bezier曲线的基础知识&#xff0c;并详细说明了如何在Visual Basic中使用 Graphics 对象的 DrawBezier 方法绘制曲线。通过理论…

分布式分片策略中,分片数量的评估与选择

分布式分片策略中,分片数量的评估与选择是影响系统性能、扩展性和运维成本的核心问题 一、分片数量评估方法论 1. ​​数据量基准模型​​ ​​单分片容量建议​​:根据Elasticsearch最佳实践,单个分片建议控制在10-50GB(冷数据可放宽至100GB),超过100GB会导致段合并效率…

Vue3高级特性:深入理解effectScope及其应用场景

系列文章目录 Vue3 组合式 API 进阶&#xff1a;深入解析 customRef 的设计哲学与实战技巧 Vue3 watchEffect 进阶使用指南&#xff1a;这些特性你可能不知道 Vue3高级特性&#xff1a;深入理解effectScope及其应用场景 文章目录系列文章目录前言一、核心概念1、什么是 effect…

Docker 中的动态配置:docker update 命令与环境变量管理

Docker 中的动态配置&#xff1a;docker update 命令与环境变量管理 在 Docker 容器的日常管理中&#xff0c;动态调整配置以适应业务需求变化是常见的操作。docker update 命令作为 Docker 平台的重要工具&#xff0c;为运行中的容器提供了便捷的配置调整方式&#xff0c;而环…

ELK 使用教程采集系统日志

作者&#xff1a;小凯 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01; 本文的宗旨在于通过易于上手实操的方式&#xff0c;教会读者完成系统ELK日志采集的对接和使用。那你知道对于一个系统的上线考察&#xff0c;必备的几样东西是什么吗&#xff1f;其实这…

小程序部分pai

wx.setClipboardData 这是微信小程序提供的 API&#xff0c;用于将数据复制到剪贴板。 Page({data: {clientInfo: {email: exampleexample.com // 假设的邮箱数据}},// 复制邮箱到剪贴板copyEmail: function() {wx.setClipboardData({data: this.data.clientInfo.email,success…

【解决方案】鸿蒙 / 矿鸿系统 Shell 无故退出问题(息屏导致)详解

平台环境 OpenHarmony 版本&#xff1a;4.1 release开发板&#xff1a;DAYU / RK3568调试工具&#xff1a;hdc 在使用 OpenHarmony 4.1 Release&#xff08;矿鸿系统&#xff09;进行开发时&#xff0c;遇到这样的问题&#xff1a; &#x1f6a8; Shell 会在一段时间后自动退出…

Data Analysis TTAD=>CNN-BiGRU-MSA

TTAO 预处理、CNN-BiGRU-MSA 模型 时序数据回归分析时序数据分析方法&#xff0c;特点&#xff1a;TTAO 预处理&#xff1a;通过三角拓扑结构增强时序特征的局部和全局关系混合模型架构&#xff1a;CNN 层提取局部特征模式BiGRU 捕获双向时序依赖多头自注意力机制进行序列建模…

python-字典、集合、序列切片、字符串操作(笔记)

一、字符串常见操作&#xff08;重点&#xff09;​1.​2.字符串无法修改#错误示范 str1"djskds" str1[2]"3"3.​str1"abcand" # 输出3 print(str1.index("and"))4.​str1"abcand" newStrstr1.replace("and",&quo…

【Android】EditText使用和监听

三三想成为安卓糕手 一&#xff1a;用户登录校验 1&#xff1a;EditText文本输入框<EditTextandroid:id"id/et_user_name"android:layout_width"match_parent"android:layout_height"wrap_content"android:inputType"number"androi…

SQL 中根据当前时间动态计算日期范围

在 SQL 中写“动态时间”通常是指根据当前时间动态计算日期范围&#xff0c;而不是写死固定日期。以下是几种常见写法&#xff08;以 SQL Server / MySQL / PostgreSQL 为例&#xff09;&#xff1a;1. 获取当前时间-- SQL Server SELECT GETDATE() AS now-- MySQL SELECT NOW(…

react-redux 类组件的 connect

store 目录下 store/reducer.js import * as actionTypes from ./constantsconst initalState {counter: 100,banners: [],recommends: [] }/*** 定义reducer函数&#xff1a;纯函数* param 参数一&#xff1a;store中目前保存的state* param 参数二&#xff1a;通过 dispatch…

数据分布是如何影响目标检测精度

文章目录一、研究背景与目标模型效果提升数据集优化二、研究问题明细各方向的关联性与核心逻辑1. 高质量数据集的高效筛选与主动学习应用2. 基于推理结果的数据补充与增强方向优化3. 多类别场景下目标尺度与模型精度的关联性4. 损失函数与数据增强对精度的量化影响5. 目标类型专…

高效批量转换Java接口为MCP服务:降低重复劳动的实战指南

高效批量转换Java接口为MCP服务:降低重复劳动的实战指南 在AI大模型技术飞速发展的今天,企业需要将现有Java接口快速适配为模型计算协议(MCP,Model Calculation Protocol)服务,以便与大模型生态无缝对接。然而,手动逐个转换接口不仅耗时耗力,还容易因人为疏忽导致错误…

Eclipse Debug 配置指南

Eclipse Debug 配置指南 引言 Eclipse 作为一款功能强大的集成开发环境(IDE),在Java开发者中享有盛誉。在开发过程中,调试功能是必不可少的。本文将详细介绍如何在Eclipse中配置调试环境,以便更高效地进行代码调试。 1. 开发环境准备 在开始配置Eclipse调试环境之前,…