什么是 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)詳解 - 高質量源碼分享平臺-免費下載各類網站源碼與模板及前沿動態資訊