高效管理 React 狀態和交互:我的自定義 Hooks 實踐

高效管理 React 狀態和交互:自定義 Hooks 實踐

在 React 中,Hooks 是一種使我們能夠在函數組件中使用狀態和副作用的強大工具。隨著項目的增大,重復的邏輯可能會出現在多個組件中,這時使用自定義 Hooks 就非常合適。它們幫助我們將業務邏輯抽象成獨立的功能模塊,提升代碼的可復用性和可維護性。

本文將介紹一些常見的自定義 Hook 實踐,包括數據獲取、去抖、狀態切換、本地存儲管理和點擊外部區域關閉組件等。通過這些自定義 Hook,我們能夠高效管理應用的狀態和交互邏輯。

1. useFetch - 數據獲取 Hook

useFetch 是一個處理數據獲取請求的自定義 Hook。它封裝了 fetch 請求的邏輯,并提供了 loadingerror 狀態,方便組件根據請求狀態渲染不同的內容。

代碼實現
import { useState, useEffect } from "react";function useFetch<T>(url: string) {const [data, setData] = useState<T | null>(null);const [loading, setLoading] = useState(true);const [error, setError] = useState<Error | null>(null);useEffect(() => {const fetchData = async () => {setLoading(true);try {const response = await fetch(url);if (!response.ok) throw new Error("Network response was not ok");const result = await response.json();setData(result);} catch (err) {setError(err as Error);} finally {setLoading(false);}};fetchData();}, [url]);return { data, loading, error };
}export default useFetch;
使用示例
const { data, loading, error } = useFetch<User[]>('/api/users');if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;return <ul>{data?.map(user => <li key={user.id}>{user.name}</li>)}</ul>;

在上述實現中,useFetch Hook 提供了一個簡潔的方式來處理 API 請求,同時通過 loadingerror 狀態來管理加載中的 UI 和錯誤展示。它封裝了所有的異步邏輯,避免了在每個組件中重復寫 fetch 請求。

2. useDebounce - 防抖處理

防抖用于避免在用戶輸入時頻繁觸發事件,尤其是在搜索框、自動完成等場景中。useDebounce 實現了延遲值的更新,直到用戶停止輸入一段時間后才觸發。

代碼實現
import { useState, useEffect } from "react";function useDebounce<T>(value: T, delay: number): T {const [debouncedValue, setDebouncedValue] = useState(value);useEffect(() => {const handler = setTimeout(() => setDebouncedValue(value), delay);return () => clearTimeout(handler);}, [value, delay]);return debouncedValue;
}export default useDebounce;
使用示例
const [searchTerm, setSearchTerm] = useState("");
const debouncedSearchTerm = useDebounce(searchTerm, 500);useEffect(() => {// 發起 API 請求或執行其他操作console.log(debouncedSearchTerm);
}, [debouncedSearchTerm]);

在上述例子中,useDebounce 延遲了對輸入值的響應,從而避免了在用戶每次輸入時都發起請求。它的使用非常適合搜索框和過濾功能,能夠提高性能。

3. useToggle - 簡化狀態切換

useToggle 是一個簡化布爾值狀態切換的 Hook,適用于需要頻繁切換狀態的場景,如顯示/隱藏彈窗、展開/收起菜單等。

代碼實現
import { useState } from "react";function useToggle(initialState = false) {const [state, setState] = useState(initialState);const toggle = () => setState(prev => !prev);return [state, toggle] as const;
}export default useToggle;
使用示例
const [isOpen, toggle] = useToggle(false);return (<div><button onClick={toggle}>Toggle</button>{isOpen && <p>Content is visible!</p>}</div>
);

useToggle 可以非常簡潔地處理布爾類型狀態的切換,避免在組件中寫冗余的 setState 代碼。

4. useLocalStorage - 本地存儲管理

useLocalStorage 是一個與 localStorage 配合的 Hook,它能夠自動處理數據的獲取、存儲和更新,確保數據在頁面刷新后仍然保持。

代碼實現
import { useState } from "react";function useLocalStorage<T>(key: string, initialValue: T) {const [storedValue, setStoredValue] = useState<T>(() => {try {const item = window.localStorage.getItem(key);return item ? JSON.parse(item) : initialValue;} catch (error) {console.error(error);return initialValue;}});const setValue = (value: T) => {try {setStoredValue(value);window.localStorage.setItem(key, JSON.stringify(value));} catch (error) {console.error(error);}};return [storedValue, setValue] as const;
}export default useLocalStorage;
使用示例
const [name, setName] = useLocalStorage("name", "John Doe");return (<div><p>Your name is: {name}</p><button onClick={() => setName("Jane Doe")}>Change Name</button></div>
);

通過 useLocalStorage,我們不僅能夠輕松地獲取和設置 localStorage 中的數據,還能在刷新頁面后保持數據狀態,適用于保存用戶設置、主題等信息。

5. useClickOutside - 外部點擊監聽

useClickOutside 是一個幫助我們監聽用戶點擊外部區域的 Hook,常用于實現點擊外部區域關閉彈窗、菜單等交互功能。

代碼實現
import { useEffect, useRef } from "react";function useClickOutside(handler: () => void) {const ref = useRef<HTMLDivElement>(null);useEffect(() => {const handleClickOutside = (event: MouseEvent) => {if (ref.current && !ref.current.contains(event.target as Node)) {handler();}};document.addEventListener('mousedown', handleClickOutside);return () => document.removeEventListener('mousedown', handleClickOutside);}, [handler]);return ref;
}export default useClickOutside;
使用示例
const [isOpen, setIsOpen] = useState(false);
const closeDropdown = () => setIsOpen(false);
const dropdownRef = useClickOutside(closeDropdown);return (<div><button onClick={() => setIsOpen(!isOpen)}>Toggle Dropdown</button>{isOpen && (<div ref={dropdownRef} style={{ border: '1px solid black', padding: '10px' }}><p>Dropdown content</p></div>)}</div>
);

useClickOutside 使得我們能夠簡化對點擊外部區域的監聽邏輯,減少了冗余代碼,提高了交互體驗。

總結

自定義 Hook 是 React 開發中非常強大的工具,可以幫助我們復用邏輯,減少冗余代碼,提升組件的可維護性和可讀性。通過本文介紹的幾個常見自定義 Hook(如 useFetchuseDebounceuseToggleuseLocalStorageuseClickOutside),我們可以輕松應對許多常見的開發需求,提高應用的性能和用戶體驗。

希望通過這些實用的自定義 Hook,你能夠更高效地管理 React 中的狀態和交互邏輯,打造更優雅的代碼結構!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/70870.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/70870.shtml
英文地址,請注明出處:http://en.pswp.cn/web/70870.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Exoplayer(MediaX)實現音頻變調和變速播放

在K歌或錄音類應用中變調是個常見需求&#xff0c;比如需要播出蘿莉音/大叔音等。變速播放在影視播放類應用中普遍存在&#xff0c;在傳統播放器Mediaplayer中這兩個功能都比較難以實現&#xff0c;特別在低版本SDK中&#xff0c;而Exoplayer作為google官方推出的Mediaplayer替…

Meta最新研究:從單張照片到3D數字人的革命性突破

隨著人工智能技術的發展,3D建模和虛擬人物生成逐漸變得更加普及和高效。Meta(前身為Facebook)的最新研究成果展示了如何僅通過一張普通手機拍攝的照片就能生成高質量、全方位的3D數字人。這項技術不僅適用于虛擬試衣、游戲角色建模,還能廣泛應用于AR/VR內容生成等領域。本文…

軟件供應鏈安全工具鏈研究系列——RASP自適應威脅免疫平臺(上篇)

1.1 基本能力 RASP是一種安全防護技術&#xff0c;運行在程序執行期間&#xff0c;使程序能夠自我監控和識別有害的輸入和行為。也就是說一個程序如果注入或者引入了RASP技術&#xff0c;那么RASP就和這個程序融為一體&#xff0c;使應用程序具備了自我防護的能力&#xff0c;…

2025-02-27 學習記錄--C/C++-PTA 7-29 刪除字符串中的子串

合抱之木&#xff0c;生于毫末&#xff1b;九層之臺&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、題目描述 ?? 二、代碼&#xff08;C語言&#xff09;?? #include <stdio.h> // 引入標準輸入輸出庫&#xff0c…

Redis---字符串SDS(簡單動態字符串)底層結構

文章目錄 什么是SDS&#xff08;簡單動態字符串&#xff09;SDS結構SDS的優點O(1) 時間復雜度獲取字符串長度避免緩沖區溢出減少內存重分配次數二進制安全兼容C語言字符串函數 SDS的操作總結 什么是SDS&#xff08;簡單動態字符串&#xff09; redis是由C語言編寫的&#xff0…

Elasticsearch:使用阿里云 AI 服務進行嵌入和重新排名

作者&#xff1a;來自 Elastic Toms Mura 將阿里云 AI 服務功能與 Elastic 結合使用。 更多閱讀&#xff0c;請參閱 “Elasticsearch&#xff1a;使用阿里 infererence API 及 semantic text 進行向量搜索”。 在本文中&#xff0c;我們將介紹如何將阿里云 AI 功能與 Elastics…

Spring Cloud Alibaba與Spring Boot、Spring Cloud版本對應關系

一、前言 在搭建SpringCloud項目環境架構的時候&#xff0c;需要選擇SpringBoot和SpringCloud進行兼容的版本號&#xff0c;因此對于選擇SpringBoot版本與SpringCloud版本的對應關系很重要&#xff0c;如果版本關系不對應&#xff0c;常見的會遇見項目啟動不起來&#xff0c;怪…

【含文檔+PPT+源碼】基于過濾協同算法的旅游推薦管理系統設計與實現

項目介紹 本課程演示的是一款基于過濾協同算法的旅游推薦管理系統設計與實現&#xff0c;主要針對計算機相關專業的正在做畢設的學生與需要項目實戰練習的 Java 學習者。 1.包含&#xff1a;項目源碼、項目文檔、數據庫腳本、軟件工具等所有資料 2.帶你從零開始部署運行本套…

MTK Android12 預裝apk可卸載

文章目錄 需求解決方法1、device/mediatek/mt6761/device.mk2、/vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_removable_vendor_list.txt3、路徑&#xff1a;4、Android.mk 需求 近期&#xff0c;客戶需要預裝一個apk&#xff0c;同時該apk要可卸載。解…

從 0 到 1,用 Python 構建超實用 Web 實時聊天應用

從 0 到 1&#xff0c;用 Python 構建超實用 Web 實時聊天應用 本文深入剖析如何運用 Python 的 Flask 框架與 SocketIO 擴展&#xff0c;搭建一個功能完備的 Web 實時聊天應用。從環境搭建、前后端代碼實現&#xff0c;到最終運行展示&#xff0c;逐步拆解關鍵步驟&#xff0…

視頻字幕識別和翻譯

下載的視頻很多不是漢語的&#xff0c;我們需要用剪映將語音識別出來作為字幕壓制到視頻中去。 剪映6.0以后語音識別需要收費&#xff0c;但是低版本還是沒有問題。 如果想要非漢語字幕轉成中文&#xff0c;剪映低版本不提供這樣功能。但是&#xff0c;用剪映導出識別字幕&am…

每天一個Flutter開發小項目 (4) : 構建收藏地點應用 - 深入Flutter狀態管理

引言 歡迎回到 每天一個Flutter開發小項目 系列博客!在前三篇博客中,我們從零開始構建了計數器應用、待辦事項列表應用,以及簡易天氣應用。您不僅掌握了 Flutter 的基礎組件和布局,還學習了網絡請求、JSON 解析等實用技能,更重要的是,我們一起探討了高效的 Flutter 學習…

Visual Studio打開文件后,中文變亂碼的解決方案

文件加載 使用Unicode&#xff08;UTF-8&#xff09;編碼加載文件 C:\WorkSpace\Assets\Scripts\UI\View\ExecuteComplateView.cs時&#xff0c;有些字節已用Unicode替換字符替換。保存該文件將不會保留原始文件內容。

OpenGL ES -> GLSurfaceView繪制點、線、三角形、正方形、圓(頂點法繪制)

XML文件 <?xml version"1.0" encoding"utf-8"?> <com.example.myapplication.MyGLSurfaceViewxmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"…

threejs 安裝教程

嗨&#xff0c;我是小路。今天主要和大家分享的主題是“threejs 安裝教程”。 在當今的數字化時代&#xff0c;用戶對視覺體驗的要求越來越高。傳統的2D網頁已經無法滿足所有需求&#xff0c;而三維&#xff08;3D&#xff09;圖形技術則為前端開發者提供了新的方向。…

win11編譯pytorch cuda128版本流程

Geforce 50xx系顯卡最低支持cuda128&#xff0c;torch cu128 release版本目前還沒有釋放&#xff0c;所以自己基于2.6.0源碼自己編譯wheel包。 1. 前置條件 1. 使用visual studio installer 安裝visual studio 2022&#xff0c;工作負荷選擇【使用c的桌面開發】,安裝完成后將…

如何安裝Vm和centos

一、VMware 安裝 &#xff08;一&#xff09;前期準備 下載 VMware 軟件&#xff1a;首先&#xff0c;你需要從 VMware 官方網站下載適合你計算機操作系統版本的 VMware Workstation 軟件安裝包。確保選擇的版本與你的主機操作系統兼容&#xff0c;例如&#xff0c;如果你的主…

OpenGL 04--GLSL、數據類型、Uniform、著色器類

一、著色器 在 OpenGL 中&#xff0c;著色器&#xff08;Shader&#xff09;是運行在 GPU 上的程序&#xff0c;用于處理圖形渲染管線中的不同階段。 這些小程序為圖形渲染管線的某個特定部分而運行。從基本意義上來說&#xff0c;著色器只是一種把輸入轉化為輸出的程序。著色器…

服務器離線部署DeepSeek

目標 本次部署的目標是在本地服務器上部署DeepSeek。但是該服務不能連接外網&#xff0c;因此只能使用離線部署的方式。為了一次完成部署。現在云服務器上進行嘗試。 云服務器部署嘗試 云服務器配置 CentOS72080Ti 11GB 安裝準備 1、上傳iso并配置為本地yum源 安裝前先將…

刪除idea recent projects 記錄

1、退出idea&#xff08;一定要全部退出idea&#xff0c;要不然刪除后&#xff0c;idea一退出&#xff0c;又保存上了&#xff09; 2、進入 C:\Users\Administrator\AppData\Roaming\JetBrains\IntelliJIdea2024.1\options 目錄 根據不同的版本號 IntelliJIdea2024.1 這個地方…