您好,登錄后才能下訂單哦!
這篇文章主要講解了“React中怎么自定義Hook”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“React中怎么自定義Hook”吧!
在 React 中你必須遵循以下命名約定:
React Component: React 組件名稱必須以大寫字母開頭,如 StatusBar 和 SaveButton。React組件還需要 返回 一些React知道如何渲染的東西,比如 JSX
。
React Hook: Hook 名必須以 use 開頭,后面跟著一個大寫字母,比如 useState (內(nèi)置)或useStatus (自定義)。與 React 組件不同的是自定義 Hook 可以返回任意值。
這個命名約定確保你始終可以查看組件,并了解其狀態(tài)、效果以及其他 React 特性可能“隱藏”的位置。例如,如果你在組件中看到 getColor() 函數(shù)調(diào)用,你可以確定它不可能包含 React state,因為其名稱不以use開頭。但是,像 useStatus() 這樣的函數(shù)調(diào)用很可能包含對其他 Hooks 的調(diào)用!
The code inside them describes what they want to do rather than how to do it .
自定義 Hooks 的核心是共享組件之間的邏輯。使用自定義 Hooks 能夠減少重復(fù)的邏輯,更重要的是,自定義 Hooks 內(nèi)部的代碼描述了它們想做什么,而不是如何做。當(dāng)你將邏輯提取到自定義Hooks 中時,你可以隱藏如何處理某些"外部系統(tǒng)"或瀏覽器 API 的調(diào)用的細節(jié),組件的代碼表達的是你的意圖,而不是實現(xiàn)細節(jié)。 下面是一個簡單的例子:
import { useState } from 'react'; function useCounter(initialValue) { const [count, setCount] = useState(initialValue); function increment() { setCount(count + 1); } return [count, increment]; }
這個自定義 Hook 叫做 useCounter
,它接受一個初始值作為參數(shù),并返回一個數(shù)組,包含當(dāng)前的計數(shù)值和一個增加計數(shù)的函數(shù)。 使用自定義 Hook 非常簡單,只需要在函數(shù)組件中調(diào)用它即可。下面是一個使用 useCounter
的例子:
import React from 'react'; import useCounter from './useCounter'; function Counter() { const [count, increment] = useCounter(0); return ( <div> <p>Count: {count}</p> <button onClick={increment}>Increment</button> </div> ); }
在這個例子中,我們導(dǎo)入了 useCounter
,并在組件中調(diào)用它。我們將返回的數(shù)組解構(gòu)為 count
和 increment
,然后在組件中使用它們。
自定義 Hooks 允許共享有狀態(tài)邏輯,但不能共享狀態(tài)本身。每個對 Hook 的調(diào)用都完全獨立于對同一個 Hook 的其他調(diào)用。 以上面的 useCounter
為例:
import useCounter from './useCounter'; function Counter() { const [count1, increment1] = useCounter(0); const [count2, increment2] = useCounter(100); return ( <div> <p>Count1: {count1}</p> <button onClick={increment1}>Increment1</button> <p>Count2: {count2}</p> <button onClick={increment2}>Increment2</button> </div> ); }
當(dāng)我們點擊 Increment2
時,并不會影響 count1
,因為每一個 useCounter
的調(diào)用都是獨立的,其內(nèi)部狀態(tài)也是獨立的。
以實現(xiàn)特定功能或目的,與具體業(yè)務(wù)無關(guān):
該 hook 返回窗口寬度的值。
import { useState, useEffect } from 'react'; function useWindowWidth() { const [windowWidth, setWindowWidth] = useState(window.innerWidth); useEffect(() => { const handleResize = () => setWindowWidth(window.innerWidth); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); return windowWidth; }
該 hook 允許你在本地存儲中存儲和檢索值。
import { useState } from 'react'; function useLocalStorage(key, initialValue) { const [storedValue, setStoredValue] = useState(() => { try { const item = window.localStorage.getItem(key); return item ? JSON.parse(item) : initialValue; } catch (error) { console.log(error); return initialValue; } }); const setValue = (value) => { try { setStoredValue(value); window.localStorage.setItem(key, JSON.stringify(value)); } catch (error) { console.log(error); } }; return [storedValue, setValue]; }
該 hook 允許你從 API 中獲取數(shù)據(jù)。
import { useState, useEffect } from 'react'; function useFetch(url) { const [data, setData] = useState(null); const [error, setError] = useState(null); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const fetchData = async () => { try { const response = await fetch(url); const json = await response.json(); setData(json); } catch (error) { setError(error); } finally { setIsLoading(false); } }; fetchData(); }, [url]); return { data, error, isLoading }; }
該 hook 允許你管理模態(tài)對話框的狀態(tài)。
//useFetch.js import {useState, useEffect} from 'react' //don't forget to give a url parameter for the function. const useFetch = (url)=>{ const [data, setData] = useState([]) const getData = async ()=>{ const response = await fetch(url) const userdata = await response.json() setData(userdata) } useEffect(()=>{ getData() },[url]) //return data that we will need in other components. return {data}; } export default useFetch;
由于 Hook 本身就是函數(shù),因此我們可以在它們之間傳遞信息。下面我們以 useUserInfo
獲取用戶信息 為例:
//useUserInfo.jsx import { useEffect,useState } from 'react' const useUserInfo = (userId) => { const [userInfo, setUserInfo] = useState({}) useEffect(() => { fetch('/user') .then(res => res.json()) .then(data => setUserInfo(data)) }, [userId]) return userInfo } //Home.jsx ... const Home = ()=>{ const [userId,setUserId] = useState('103') const useInfo = useUserInfo(userId) return ( <> <div>name:{userInfo.name}</div> <div>age:{userInfo.age}</div> ... </> ) }
我們將 用戶 id 保存在 userId
狀態(tài)變量中,當(dāng)用戶進行某一操作 setUserId
時,由于 useState
為我們提供了 userId
狀態(tài)變量的最新值,因此我們可以將它作為參數(shù)傳遞給自定義的 useUserInfo
Hook:
const [userId,setUserId] = useState('103') const userInfo = useUserInfo(userId)
此時,我們的 userInfo
會隨著 userId 的改變而更新。
This section describes an experimental API that has not yet been released in a stable version of React. 本節(jié)描述了一個尚未在 React 穩(wěn)定版本中發(fā)布的 實驗性 API。
你可能希望讓組件自定義其行為,而不是完全地將邏輯封裝 Hooks 中,我們可以通過將 event handlers
作為參數(shù)傳遞給 Hooks,下面是一個聊天室的例子: useChatRoom
接受一個服務(wù)端 url 和 roomId,當(dāng)調(diào)用這個 Hook 的時候,會進行連接,
export function useChatRoom({ serverUrl, roomId }) { useEffect(() => { const options = { serverUrl: serverUrl, roomId: roomId }; const connection = createConnection(options); connection.connect(); connection.on('message', (msg) => { showNotification('New message: ' + msg); }); return () => connection.disconnect(); }, [roomId, serverUrl]); }
假設(shè)當(dāng)連接成功時,你想將此邏輯移回你的組件:
export default function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); useChatRoom({ roomId: roomId, serverUrl: serverUrl, onReceiveMessage(msg) { showNotification('New message: ' + msg); } }); // ...
要做到這一點,改變你的自定義 Hook ,把 onReceiveMessage
作為它的命名選項之一:
export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) { useEffect(() => { const options = { serverUrl: serverUrl, roomId: roomId }; const connection = createConnection(options); connection.connect(); connection.on('message', (msg) => { onReceiveMessage(msg); }); return () => connection.disconnect(); }, [roomId, serverUrl, onReceiveMessage]); // ? All dependencies declared }
這可以工作,但是當(dāng)你的自定義 Hook 接受事件處理程序時,你還可以做一個改進。 在 onReceiveMessage
上添加依賴并不理想,因為它會導(dǎo)致每次組件重新渲染時聊天都重新連接。將此事件處理程序包裝到 EffectEvent
中以將其從依賴項中移除:
import { useEffect, useEffectEvent } from 'react'; // ... export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) { const onMessage = useEffectEvent(onReceiveMessage); useEffect(() => { const options = { serverUrl: serverUrl, roomId: roomId }; const connection = createConnection(options); connection.connect(); connection.on('message', (msg) => { onMessage(msg); }); return () => connection.disconnect(); }, [roomId, serverUrl]); // ? All dependencies declared }
現(xiàn)在不會在每次重新渲染聊天室組件時進行重新連接。
ahooks 一套由阿里巴巴開源的 React Hooks 庫,封裝了大量好用的 Hooks。
react-use 一個必不可少的 React Hooks 集合。其包含了傳感器、用戶界面、動畫效果、副作用、生命周期、狀態(tài)這六大類的Hooks。
useHooks 一組易于理解的 React Hook集合。
react-recipes 一個包含流行的自定義 Hook 的 React Hooks 實用程序庫。
Rhooks 一組基本的 React 自定義Hooks。
react-hanger 一組有用的 hooks,用于特定于某些基本類型的狀態(tài)更改輔助函數(shù)。
Beautiful React Hook 一組漂亮的(希望有用的)React hooks 來加速你的組件和 hooks 開發(fā)。
Awesome React Hooks 一個很棒的 React Hooks 資源集合,該集合包含React Hooks教程、視頻、工具,Hooks列表。其中Hooks列表中包含了眾多實用的自定義Hooks。
SWR 一個用于獲取數(shù)據(jù)的 React Hooks 庫。只需一個Hook,就可以顯著簡化項目中的數(shù)據(jù)獲取邏輯。
React Hook Form 一個用于表單狀態(tài)管理和驗證的 React Hooks (Web + React Native)。
感謝各位的閱讀,以上就是“React中怎么自定義Hook”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對React中怎么自定義Hook這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。