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
英文地址,請注明出處:http://en.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調試環境之前,…