React中的常用Hooks分享
useState
useSate用于在函數(shù)組件中添加狀態(tài)管理。它返回一個(gè)狀態(tài)值和更新該狀態(tài)值的函數(shù)。 使用時(shí)一些特點(diǎn)和注意事項(xiàng)
- 正確定義初始狀態(tài):在使用
useState時(shí),需要為初始狀態(tài)提供一個(gè)合適的值。確保初始狀態(tài)的類型與后續(xù)狀態(tài)的類型保持一致,避免出現(xiàn)類型錯(cuò)誤。 - 解構(gòu)數(shù)組:
useState返回一個(gè)包含狀態(tài)值和更新?tīng)顟B(tài)值的函數(shù)的數(shù)組,通??梢允褂脭?shù)組解構(gòu)來(lái)獲取它們。例如:const [state, setState] = useState(initialState);。這樣做可以提高代碼的可讀性。 - 更新?tīng)顟B(tài):使用
setState函數(shù)來(lái)更新?tīng)顟B(tài)值。注意,setState并不會(huì)像類組件中的setState方法一樣自動(dòng)合并更新,而是替換整個(gè)狀態(tài)對(duì)象。因此,在更新?tīng)顟B(tài)時(shí),請(qǐng)確保包含了所有需要保留的狀態(tài)值,而不僅僅是更新的部分。 - 異步更新:由于狀態(tài)更新是異步的,多次連續(xù)調(diào)用
setState不會(huì)立即反映到狀態(tài)值上。如果需要基于先前的狀態(tài)進(jìn)行更新,可以使用回調(diào)函數(shù)的形式調(diào)用setState。例如:setState(prevState => prevState + 1);。 - 函數(shù)式更新:當(dāng)新的狀態(tài)值依賴于先前的狀態(tài)值時(shí),可以使用函數(shù)式更新形式。這樣可以避免依賴于當(dāng)前狀態(tài)的值,并確保獲取到最新的狀態(tài)。例如:
setState(prevState => prevState + 1);。
import { Button } from 'antd';
import React, { useState } from 'react';
const Test = (props: any) => {
const [count, setCount] = useState(0);
const onChange = () => {
setCount(count + 1);
// 異步更新有時(shí)候會(huì)不生效,需要這樣寫
setCount(pre => pre + 1);
}
return (
<div>
{count}
<Button onClick={onChange}>點(diǎn)擊</Button>
</div>
)
}
export default Test;useEffect
用于處理副作用,例如數(shù)據(jù)獲取、訂閱、事件處理等。它在組件渲染完成后執(zhí)行,并可以在組件更新時(shí)重新執(zhí)行。 useEffect 是 React 中常用的 Hook 之一,用于處理副作用操作,例如數(shù)據(jù)獲取、訂閱、事件監(jiān)聽(tīng)等。useEffect 在組件渲染后執(zhí)行,并可以在組件更新時(shí)重新執(zhí)行。
useEffect 接受兩個(gè)參數(shù):一個(gè)副作用函數(shù)和一個(gè)依賴項(xiàng)數(shù)組。
副作用函數(shù)是在組件渲染后執(zhí)行的函數(shù)。它可以包含任何副作用操作,例如訂閱事件、發(fā)送網(wǎng)絡(luò)請(qǐng)求、操作 DOM 等。該函數(shù)可以返回一個(gè)清理函數(shù),用于在組件卸載或重新渲染之前執(zhí)行清理操作。
依賴項(xiàng)數(shù)組是一個(gè)可選的參數(shù),用于指定副作用函數(shù)依賴的值。當(dāng)依賴項(xiàng)數(shù)組發(fā)生變化時(shí),useEffect 將重新執(zhí)行副作用函數(shù)。如果不提供依賴項(xiàng)數(shù)組,副作用函數(shù)將在每次組件更新時(shí)都執(zhí)行。如果傳入一個(gè)空數(shù)組 [],副作用函數(shù)將只在組件首次渲染后執(zhí)行,不會(huì)重新執(zhí)行。
以下是 useEffect 的基本用法:
import { useEffect } from 'react';
function MyComponent() {
// 無(wú)依賴項(xiàng),會(huì)一值執(zhí)行
useEffect(() => {
// 操作
});
// 依賴項(xiàng)為空,組件初始化會(huì)執(zhí)行一次
useEffect(() => {
// 操作
},[]);
// 依賴于某個(gè)變量或函數(shù),在依賴項(xiàng)發(fā)生變化后觸發(fā)
useEffect(() => {
// 在組件渲染后執(zhí)行副作用操作
// 返回一個(gè)清理函數(shù)(可選)
return () => {
// 在組件卸載或重新渲染之前執(zhí)行清理操作
//該清理函數(shù)將在組件卸載或重新渲染之前執(zhí)行
};
}, [/* 依賴項(xiàng)數(shù)組 */]);
return (
<div></div>
);
}下面是一些關(guān)于 useEffect 的常見(jiàn)用法和注意事項(xiàng):
- 數(shù)據(jù)獲取和訂閱:可以在
useEffect中進(jìn)行異步操作,例如發(fā)起網(wǎng)絡(luò)請(qǐng)求獲取數(shù)據(jù)或訂閱事件。確保在清理函數(shù)中取消訂閱或中斷請(qǐng)求,以避免內(nèi)存泄漏。 - 依賴項(xiàng)數(shù)組的使用:通過(guò)依賴項(xiàng)數(shù)組,可以控制副作用函數(shù)的執(zhí)行時(shí)機(jī)。只有當(dāng)依賴項(xiàng)發(fā)生變化時(shí),才會(huì)重新執(zhí)行副作用函數(shù)。如果不提供依賴項(xiàng)數(shù)組,則副作用函數(shù)將在每次組件更新時(shí)都執(zhí)行。
- 空依賴項(xiàng)數(shù)組的使用:如果副作用函數(shù)不依賴任何狀態(tài)或?qū)傩?,可以傳入一個(gè)空數(shù)組
[],使副作用函數(shù)僅在組件首次渲染后執(zhí)行一次。 - 清理函數(shù)的使用:如果副作用函數(shù)需要進(jìn)行清理操作,例如取消訂閱或清除定時(shí)器,請(qǐng)?jiān)诟弊饔煤瘮?shù)中返回一個(gè)清理函數(shù)。該清理函數(shù)將在組件卸載或重新渲染之前執(zhí)行。
- 異步操作和更新?tīng)顟B(tài):在副作用函數(shù)中進(jìn)行異步操作時(shí),確保正確處理狀態(tài)的更新。使用函數(shù)式更新或通過(guò)依賴項(xiàng)數(shù)組傳入更新的狀態(tài)。
useContext
當(dāng)使用 useContext Hook 時(shí),可以方便地在 React 組件中訪問(wèn)全局的上下文數(shù)據(jù)。下面是一個(gè)使用 useContext 的簡(jiǎn)單例子:
首先,創(chuàng)建一個(gè)上下文對(duì)象:
import React, { createContext } from 'react';
// 創(chuàng)建上下文對(duì)象
const MyContext = createContext();
// 上下文提供器
function MyContextProvider({ children }) {
const sharedData = 'Shared Data';
return (
<MyContext.Provider value={sharedData}>
{children}
</MyContext.Provider>
);
}在上面的例子中,創(chuàng)建了一個(gè)名為 MyContext 的上下文對(duì)象,并通過(guò) MyContext.Provider 提供器將共享數(shù)據(jù) sharedData 傳遞給子組件。
然后,在需要訪問(wèn)上下文數(shù)據(jù)的組件中使用 useContext:
import React, { useContext } from 'react';
function MyComponent() {
const sharedData = useContext(MyContext);
return (
<div>
Shared Data: {sharedData}
</div>
);
}在上面的例子中,創(chuàng)建了一個(gè)名為 MyContext 的上下文對(duì)象,并通過(guò) MyContext.Provider 提供器將共享數(shù)據(jù) sharedData 傳遞給子組件。
然后,在需要訪問(wèn)上下文數(shù)據(jù)的組件中使用 useContext:
import React, { useContext } from 'react';
function MyComponent() {
const sharedData = useContext(MyContext);
return (
<div>
Shared Data: {sharedData}
</div>
);
}使用 useContext Hook 來(lái)獲取 MyContext 上下文的值,并將其賦值給 sharedData 變量。然后,可以在組件中使用該值進(jìn)行渲染或其他操作。
注意事項(xiàng):
- 使用
useContext前,確保已在組件樹(shù)中的某個(gè)地方提供了上下文。在上面的例子中,通過(guò)MyContext.Provider提供器在組件樹(shù)中提供了上下文數(shù)據(jù)。 - 上下文數(shù)據(jù)的更新:當(dāng)上下文數(shù)據(jù)發(fā)生變化時(shí),使用
useContext的組件會(huì)自動(dòng)重新渲染。這意味著,當(dāng)共享數(shù)據(jù)發(fā)生更改時(shí),使用該上下文的所有組件都會(huì)更新。 - 上下文嵌套:React 允許上下文進(jìn)行嵌套。在嵌套的情況下,使用
useContext會(huì)獲取最接近的上層提供器的值。 - 上下文的性能優(yōu)化:當(dāng)上下文數(shù)據(jù)較大或頻繁變化時(shí),可以使用
React.memo、useMemo或自定義的優(yōu)化方法來(lái)優(yōu)化上下文的性能。 - 避免過(guò)度使用上下文:上下文是用于共享數(shù)據(jù)的有用工具,但過(guò)度使用可能導(dǎo)致組件之間的耦合性增加。請(qǐng)?jiān)谛枰蚕頂?shù)據(jù)的組件之間仔細(xì)考慮使用上下文的合適程度。
使用 useContext 可以方便地訪問(wèn)和共享上下文數(shù)據(jù),但請(qǐng)確保在使用前提供了上下文,并注意上述的注意事項(xiàng),以確保正確使用上下文功能。
useReducer
useReducer 是 React 中的一個(gè)常用 Hook,用于管理具有復(fù)雜狀態(tài)邏輯的組件。它類似于 Redux 中的 reducer,接收一個(gè)狀態(tài)和操作函數(shù),并返回新的狀態(tài)和派發(fā)操作的函數(shù)。
使用 useReducer 時(shí),需要定義一個(gè) reducer 函數(shù)和初始狀態(tài)。
reducer 函數(shù)接收當(dāng)前狀態(tài)和一個(gè)操作(action),并根據(jù)操作的類型來(lái)更新?tīng)顟B(tài)。它返回更新后的狀態(tài)。reducer 函數(shù)的定義類似于 Redux 中的 reducer:
function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
}初始狀態(tài)是狀態(tài)的初始值:
const initialState = { count: 0 };然后,使用 useReducer Hook 在組件中應(yīng)用 reducer:
import React, { useReducer } from 'react';
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
Count: {state.count}
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
</div>
);
}在上述例子中,我們使用 useReducer 定義了狀態(tài) state 和派發(fā)操作的函數(shù) dispatch。我們可以根據(jù)操作的類型通過(guò)調(diào)用 dispatch 函數(shù)來(lái)派發(fā)操作,并由 reducer 函數(shù)來(lái)更新?tīng)顟B(tài)。
useReducer 在處理具有復(fù)雜狀態(tài)邏輯的組件時(shí)非常有用。以下是一些使用場(chǎng)景:
- 計(jì)數(shù)器:可以使用 useReducer 來(lái)管理計(jì)數(shù)器的狀態(tài)和操作,例如增加、減少計(jì)數(shù)等。
- 表單處理:使用 useReducer 可以更好地管理表單的狀態(tài)和用戶輸入的操作,以及進(jìn)行表單驗(yàn)證等復(fù)雜邏輯。
- 數(shù)據(jù)列表:當(dāng)處理復(fù)雜的數(shù)據(jù)列表時(shí),使用 useReducer 可以更好地管理數(shù)據(jù)的加載、篩選、排序等操作,以及處理分頁(yè)等功能。
總的來(lái)說(shuō),useReducer 適用于需要管理復(fù)雜狀態(tài)邏輯的組件,并且可以幫助組織和更新?tīng)顟B(tài),以及處理相關(guān)的操作。它可以代替使用 useState 的方式,特別適合管理具有多個(gè)操作類型和相關(guān)狀態(tài)的組件。
useMemo
useMemo 是 React 中的一個(gè)常用 Hook,用于在組件渲染過(guò)程中進(jìn)行性能優(yōu)化,避免不必要的計(jì)算和重復(fù)渲染。
useMemo 接受兩個(gè)參數(shù):一個(gè)計(jì)算函數(shù)和依賴項(xiàng)數(shù)組。它會(huì)在組件渲染過(guò)程中執(zhí)行計(jì)算函數(shù),并將計(jì)算結(jié)果緩存起來(lái)。只有當(dāng)依賴項(xiàng)數(shù)組中的值發(fā)生變化時(shí),才會(huì)重新執(zhí)行計(jì)算函數(shù)。
使用 useMemo 可以避免在每次渲染時(shí)重復(fù)計(jì)算耗時(shí)的操作,并且可以根據(jù)依賴項(xiàng)的變化來(lái)更新計(jì)算結(jié)果。以下是一些 useMemo 的常見(jiàn)使用場(chǎng)景:
- 計(jì)算結(jié)果的緩存:當(dāng)需要根據(jù)某些輸入計(jì)算結(jié)果時(shí),可以使用 useMemo 緩存計(jì)算結(jié)果,避免重復(fù)計(jì)算。這在計(jì)算量較大的場(chǎng)景下特別有用。
- 避免不必要的重渲染:當(dāng)一個(gè)組件依賴于某個(gè)狀態(tài)或?qū)傩?,但這些狀態(tài)或?qū)傩缘淖兓⒉粫?huì)影響到組件的渲染結(jié)果時(shí),可以使用 useMemo 來(lái)緩存渲染結(jié)果,避免不必要的重渲染。
- 優(yōu)化子組件的渲染:當(dāng)將一個(gè)計(jì)算結(jié)果作為屬性傳遞給子組件時(shí),可以使用 useMemo 緩存計(jì)算結(jié)果,以避免在每次父組件渲染時(shí)都重新計(jì)算并傳遞給子組件。
- 性能敏感的比較操作:當(dāng)需要進(jìn)行一些性能敏感的比較操作,例如深度比較對(duì)象或數(shù)組時(shí),可以使用 useMemo 緩存比較結(jié)果,以避免在每次渲染時(shí)重新執(zhí)行比較操作。 下面是一個(gè)使用 useMemo 的簡(jiǎn)單例子,展示如何緩存計(jì)算結(jié)果以提高性能:
import React, { useMemo, useState } from 'react';
function ExpensiveComponent() {
// 假設(shè)這里有一個(gè)計(jì)算耗時(shí)的函數(shù)
function calculateExpensiveValue() {
// ... 復(fù)雜的計(jì)算邏輯 ...
console.log('Calculating expensive value...');
return Math.random();
}
// 使用 useMemo 緩存計(jì)算結(jié)果
const expensiveValue = useMemo(() => calculateExpensiveValue(), []);
return (
<div>
Expensive Value: {expensiveValue}
</div>
);
}
function App() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<ExpensiveComponent />
</div>
);
}在上述代碼中,有一個(gè) ExpensiveComponent 組件,其中包含一個(gè)計(jì)算耗時(shí)的函數(shù) calculateExpensiveValue。為了避免在每次渲染時(shí)都重新計(jì)算 expensiveValue,使用 useMemo 緩存計(jì)算結(jié)果。
通過(guò)將 calculateExpensiveValue 函數(shù)作為 useMemo 的第一個(gè)參數(shù),并將空數(shù)組作為依賴項(xiàng)傳遞給 useMemo,確保只在組件首次渲染時(shí)執(zhí)行一次計(jì)算,并將結(jié)果緩存起來(lái)。當(dāng) count 發(fā)生變化時(shí),ExpensiveComponent 重新渲染,但不會(huì)觸發(fā)計(jì)算函數(shù)的重新執(zhí)行。
useLayoutEffect
useLayoutEffect 是 React 中的一個(gè) Hook,與 useEffect 類似,但它在 DOM 變更之后同步執(zhí)行,而不是在瀏覽器繪制之后執(zhí)行。它會(huì)在瀏覽器布局和繪制之前同步執(zhí)行回調(diào)函數(shù)。
使用 useLayoutEffect 可以在瀏覽器布局完成后立即執(zhí)行一些操作,以確保獲取到最新的 DOM 布局信息,并在下一次渲染之前同步地更新 UI。這在需要準(zhǔn)確地測(cè)量 DOM 元素的尺寸、位置或進(jìn)行 DOM 操作時(shí)非常有用。
下面是一個(gè)使用 useLayoutEffect 的簡(jiǎn)單例子:
import React, { useRef, useLayoutEffect } from 'react';
function MeasureElement() {
const ref = useRef();
useLayoutEffect(() => {
// 在瀏覽器布局完成后立即執(zhí)行操作
const element = ref.current;
const { width, height } = element.getBoundingClientRect();
// 使用測(cè)量結(jié)果進(jìn)行操作
console.log('Element size:', width, height);
}, []);
return <div ref={ref}>Measure me!</div>;
}
function App() {
return (
<div>
<MeasureElement />
</div>
);
}在上述例子中,創(chuàng)建了一個(gè)名為 MeasureElement 的組件,在組件內(nèi)部使用了 useLayoutEffect。在 useLayoutEffect 的回調(diào)函數(shù)中,我們可以獲取到被測(cè)量元素的最新布局信息,并進(jìn)行相應(yīng)的操作。
在這個(gè)例子中,我們使用 getBoundingClientRect 方法獲取被測(cè)量元素的寬度和高度,并將結(jié)果打印到控制臺(tái)。這個(gè)操作在瀏覽器布局完成后同步執(zhí)行,確保我們獲取到的尺寸是最新的。
需要注意的是,由于 useLayoutEffect 在瀏覽器布局之后同步執(zhí)行,因此它的執(zhí)行會(huì)阻塞瀏覽器的渲染過(guò)程。因此,只有在需要同步更新 UI 或測(cè)量 DOM 元素時(shí)才使用 useLayoutEffect,避免造成性能問(wèn)題。
到此這篇關(guān)于React中的常用Hooks分享的文章就介紹到這了,更多相關(guān)React常用Hooks內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入理解React調(diào)度(Scheduler)原理
本文主要介紹了深入理解React調(diào)度(Scheduler)原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
React中g(shù)etDefaultProps的使用小結(jié)
React中的getDefaultProps功能允許開(kāi)發(fā)者為類組件定義默認(rèn)屬性,提高組件的靈活性和容錯(cuò)性,本文介紹了getDefaultProps的作用、語(yǔ)法以及最佳實(shí)踐,并探討了其他替代方案,如函數(shù)組件中的默認(rèn)參數(shù)、高階組件和ContextAPI等,理解這些概念有助于提升代碼的可維護(hù)性和用戶體驗(yàn)2024-09-09
react實(shí)現(xiàn)復(fù)選框全選和反選組件效果
這篇文章主要為大家詳細(xì)介紹了react實(shí)現(xiàn)復(fù)選框全選和反選組件效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08
React實(shí)現(xiàn)過(guò)渡效果更新時(shí)間展示功能
創(chuàng)建一個(gè)組件,實(shí)時(shí)展示時(shí)分秒,并且動(dòng)態(tài)更新數(shù)據(jù),這篇文章主要介紹了React實(shí)現(xiàn)過(guò)渡效果更新時(shí)間展示功能,需要的朋友可以參考下2024-07-07
React Hooks如何主動(dòng)更新Hooks組件
這篇文章主要介紹了React Hooks如何主動(dòng)更新Hooks組件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
React?的?useReducer?和?Redux?的區(qū)別及什么情況下應(yīng)該使用?useReducer
這篇文章主要介紹了React的useReducer和Redux的區(qū)別及什么情況下應(yīng)該使用useReducer,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2025-06-06
React報(bào)錯(cuò)解決之ref返回undefined或null
最近使用react做個(gè)滾動(dòng)監(jiān)聽(tīng)獲取更多數(shù)據(jù)效果,當(dāng)想獲取dom時(shí)發(fā)現(xiàn)怎么也獲取不到,下面這篇文章主要給大家介紹了關(guān)于React報(bào)錯(cuò)解決之ref返回undefined或null的相關(guān)資料,需要的朋友可以參考下2022-08-08

