最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

react之自定義hooks

2023-07-03 13:24 作者:chaojilaji123  | 我要投稿

原文合集地址如下,有需要的朋友可以關(guān)注

本文地址

合集地址

任何相對(duì)獨(dú)立、復(fù)用性強(qiáng)的邏輯,都可以 extract 為自定義 Hook,自定義 Hook 是一種復(fù)用 React 的狀態(tài)邏輯的函數(shù)。 自定義 Hook 的主要特點(diǎn)是:

  • 抽象組件間的狀態(tài)邏輯,方便復(fù)用

  • 讓功能組件更純粹,更易于維護(hù)

  • 自定義 Hook 可以調(diào)用其他 Hook

為什么要用自定義 Hook?

  1. 提煉能復(fù)用的邏輯 許多組件有相似的狀態(tài)邏輯,使用自定義 Hook 可以很方便地提取出來復(fù)用。

  2. 解決復(fù)雜組件的可讀性問題 使用自定義 Hook 將復(fù)雜組件拆分為更小的功能獨(dú)立的函數(shù),有助于提高代碼的可讀性。

  3. 管理數(shù)據(jù)更新 使用獨(dú)立的 Hook 函數(shù)來管理數(shù)據(jù)請(qǐng)求、處理異步邏輯、數(shù)據(jù)緩存等,易于維護(hù)。

  4. 分離狀態(tài)邏輯 自定義 Hook 讓函數(shù)組件更純粹,只負(fù)責(zé) UI,狀態(tài)邏輯則交給 Hook。

  5. 調(diào)用其他 Hook 自定義 Hook 本身還可以調(diào)用 useState、useEffect 等其他 React Hook。

以下是我總結(jié)的一些常用的hooks

1、useUpdateEffect

useUpdateEffect作用

useUpdateEffect 是一個(gè)自定義的 React Hook,用于在組件更新時(shí)執(zhí)行副作用操作。它類似于 React 的 useEffect,但是會(huì)忽略組件的初始渲染階段,只在組件更新時(shí)執(zhí)行副作用操作。

在 React 中,useEffect 會(huì)在組件的每次渲染(包括初始渲染)完成后執(zhí)行副作用操作。但有時(shí)候我們只想在組件更新時(shí)執(zhí)行某些操作,而不關(guān)心初始渲染階段的操作。這就是 useUpdateEffect 的用途。

以下是一個(gè)示例:

import?{?useEffect,?useState?}?from?'react';

function?MyComponent()?{
??const?[count,?setCount]?=?useState(0);

??useEffect(()?=>?{
????console.log('useEffect?-?Component?has?rendered');
??});

??useUpdateEffect(()?=>?{
????console.log('useUpdateEffect?-?Component?has?updated');
??});

??return?(
????<div>
??????<p>Count:?{count}</p>
??????<button?onClick={()?=>?setCount(count?+?1)}>Increment</button>
????</div>

??);
}

在上述示例中,當(dāng)點(diǎn)擊 "Increment" 按鈕時(shí),count 的值會(huì)增加并觸發(fā)組件的重新渲染。useEffect 會(huì)在每次渲染后執(zhí)行,而 useUpdateEffect 只會(huì)在組件更新時(shí)執(zhí)行。

通過使用 useUpdateEffect,你可以在組件更新時(shí)執(zhí)行一些特定的副作用操作,如請(qǐng)求數(shù)據(jù)、更新狀態(tài)等,而不需要關(guān)心初始渲染階段的操作。

為什么會(huì)需要用到useUpdateEffect

在某些情況下,我們希望在 React 組件更新時(shí)執(zhí)行一些特定的副作用操作,而不在初始渲染階段執(zhí)行這些操作。這種情況下,我們可以使用類似于 useUpdateEffect 的自定義 Hook。

以下是一些使用 useUpdateEffect 的常見情況:

  1. 避免初始渲染時(shí)執(zhí)行副作用:有些副作用操作可能只需要在組件更新時(shí)執(zhí)行,例如發(fā)送網(wǎng)絡(luò)請(qǐng)求、更新特定狀態(tài)等。使用 useUpdateEffect 可以確保這些副作用操作在初始渲染時(shí)被跳過,只在組件更新時(shí)執(zhí)行。

  2. 監(jiān)聽特定狀態(tài)的變化:有時(shí)我們只關(guān)心特定狀態(tài)的變化,并希望在狀態(tài)發(fā)生變化時(shí)執(zhí)行相應(yīng)的操作。通過將狀態(tài)值作為 useUpdateEffect 的依賴項(xiàng),可以確保副作用操作只在這些狀態(tài)發(fā)生變化時(shí)觸發(fā)。

  3. 更新外部資源或庫:有些第三方庫或外部資源可能需要在組件更新時(shí)進(jìn)行更新或重新初始化。使用 useUpdateEffect 可以確保在組件更新時(shí)調(diào)用相應(yīng)的函數(shù)或方法,以便正確地更新這些外部資源。

通過使用 useUpdateEffect,我們可以更加精確地控制副作用操作的觸發(fā)時(shí)機(jī),避免不必要的重復(fù)執(zhí)行,以及在需要時(shí)處理特定的更新邏輯。

需要注意的是,React 自帶的 useEffect 可以處理大多數(shù)情況下的副作用操作,而 useUpdateEffect 是在某些特定場(chǎng)景下的補(bǔ)充工具。在大多數(shù)情況下,使用 useEffect 即可滿足需求。

自定義useUpdateEffect

要自定義一個(gè)類似于 useUpdateEffect 的自定義 Hook,你可以借助 React 的 useEffectuseRef Hooks 來實(shí)現(xiàn)。以下是一個(gè)示例代碼:

import?{?useEffect,?useRef?}?from?'react';

function?useUpdateEffect(effect,?dependencies)?{
??const?isMounted?=?useRef(false);

??useEffect(()?=>?{
????if?(isMounted.current)?{
??????effect();
????}?else?{
??????isMounted.current?=?true;
????}
??},?dependencies);
}

//?使用示例
function?MyComponent()?{
??const?[count,?setCount]?=?useState(0);

??useUpdateEffect(()?=>?{
????console.log('Component?has?updated');
??},?[count]);

??return?(
????<div>
??????<p>Count:?{count}</p>
??????<button?onClick={()?=>?setCount(count?+?1)}>Increment</button>
????</div>

??);
}

在上述示例中,我們創(chuàng)建了一個(gè)名為 useUpdateEffect 的自定義 Hook。它接受兩個(gè)參數(shù):effectdependencies。在內(nèi)部,我們使用了 useRef 來創(chuàng)建一個(gè)標(biāo)記是否已經(jīng)完成初始渲染的變量 isMounted。

useEffect 中,我們檢查 isMounted 的值。如果 isMounted 的值為 true,則表示組件已經(jīng)完成了初始渲染,此時(shí)執(zhí)行傳入的 effect 函數(shù)。否則,將 isMounted 的值設(shè)置為 true,表示組件已完成初始渲染。

在使用時(shí),你可以像使用 useEffect 一樣,傳入 effect 函數(shù)和依賴項(xiàng)數(shù)組 dependencies,并且 effect 函數(shù)只會(huì)在組件更新時(shí)執(zhí)行。

2、useTitle

useTitle 是一個(gè)相對(duì)經(jīng)典的自定義 React Hook ,用來控制瀏覽器標(biāo)題:

定義useTitle

import?{?useState,?useEffect?}?from?'react';

function?useTitle(initialTitle)?{
??const?[title,?setTitle]?=?useState(initialTitle);
?
??useEffect(()?=>?{
????document.title?=?title;
??},?[title]);

??return?setTitle;
}

使用useTitle:

function?Page()?{
??const?setTitle?=?useTitle('Default?Title');
?
??return?(
????<Button?onClick={()?=>?setTitle('New?Title')}>
??????Click?me
????</Button>

??)
}

點(diǎn)擊按鈕后,瀏覽器標(biāo)題會(huì)變成"New Title"。 它的工作原理是:

  • 保存標(biāo)題的 state ,并記錄修改 setTitle()

  • 用 useEffect 監(jiān)測(cè) title 變化,設(shè)置 document.title 所以一旦我們調(diào)用 setTitle('New Title') 改變 state ,useEffect 就會(huì)執(zhí)行,設(shè)置新的瀏覽器標(biāo)題。 useTitle 的優(yōu)點(diǎn)是:

  • 抽象出設(shè)置標(biāo)題的邏輯,任何組件都可以共享

  • 讓組件更純粹,只需要調(diào)用 setTitle() 接口即可 我們甚至可以抽象為更通用的 Hook:

js
function?useDocumentTitle(title)?{
??useEffect(()?=>?{
????document.title?=?title;
??},?[title]);
}

function?Page()?{
??useDocumentTitle('Default?Title');
??//?...
}

通過自定義 Hook ,可以方便地在任何組件控制標(biāo)題。

3、useForceUpdate

定義useForceUpdate

import?{?useState?}?from?'react';

function?useForceUpdate()?{
??const?[value,?setValue]?=?useState(0);?
??
??return?()?=>?{
????setValue(value?=>?value?+?1);?
??};
}

useForceUpdate的使用

const?forceUpdate?=?useForceUpdate();

//?模擬更新組件
forceUpdate();

這個(gè) Hook 返回了一個(gè)更新函數(shù)。在調(diào)用這個(gè)函數(shù)時(shí),使用useState強(qiáng)制組件重新渲染。 這是基于以下原理實(shí)現(xiàn)的:

  • useState()會(huì)觸發(fā)組件重新渲染

  • state變化后,組件函數(shù)會(huì)重新執(zhí)行 函數(shù)式組件只有 state 或 props 變化時(shí)才會(huì)更新。 使用此 Hook 我們可以主動(dòng)觸發(fā)組件更新。 比如在使用過時(shí)數(shù)據(jù)時(shí):

//?過時(shí)數(shù)據(jù)?
const?{?data?}?=?useSomeHook();

//?更新組件
const?forceUpdate?=?useForceUpdate();
setInterval(()?=>?{
??forceUpdate();
},?5000);

每5秒強(qiáng)制組件一次,保證拿到最新數(shù)據(jù)。

4、useDebounce

定義

const?useDebounce?=?(value,?delay)?=>?{
??const?[debouncedValue,?setDebouncedValue]?=?useState(value);

??useEffect(()?=>?{
????const?handler?=?setTimeout(()?=>?{
??????setDebouncedValue(value);???
????},?delay);
????return?()?=>?{
??????clearTimeout(handler);?
????};
??},?[]);?//?設(shè)為空數(shù)組[]

??useEffect(()?=>?{
????clearTimeout(handler);?????
????handler?=?setTimeout(()?=>?{
??????setDebouncedValue(value);
????},?delay);
??},?[value]);??//?只依賴?value

??return?debouncedValue;
};

使用

const?inputValue?=?useDebounced(searchTerm,?500);

這里 每當(dāng)searchTerm變化時(shí),會(huì)設(shè)置一個(gè) 500ms 的定時(shí)器。只有500ms內(nèi)沒有再改變searchTerm,才會(huì)更新debouncedValue。 這實(shí)現(xiàn)了防抖功能:在一定時(shí)間內(nèi)停止觸發(fā), 只執(zhí)行最后的動(dòng)作。

5、useThrottle

定義

const?useThrottle?=?(value,?limit)?=>?{
??const?[throttledValue,?setThrottledValue]?=?useState(value);

??useEffect(()?=>?{
????const?handler?=?setTimeout(()?=>?{
??????setThrottledValue(value);
????},?limit);
????return?()?=>?{
??????clearTimeout(handler);
????};
??},?[]);?//?應(yīng)設(shè)為空數(shù)組[]??
??
??useEffect(()?=>?{
????clearTimeout(handler);
????handler?=?setTimeout(()?=>?{
??????setThrottledValue(value);????
????},?limit);
??},?[value,?limit]);?
??
??return?throttledValue;??
};

使用

const?throttledValue?=?useThrottle(inputValue,?1000);

這里 每次inputValue變化時(shí),會(huì)開始一個(gè)計(jì)時(shí)器。1s后才會(huì)更新throttledValue,實(shí)現(xiàn)了節(jié)流功能。

6、useInterval

定義

const?useInterval?=?(callback,?delay)?=>?{
??const?savedCallback?=?useRef();

??useEffect(()?=>?{
????savedCallback.current?=?callback;
??});?

??useEffect(()?=>?{
????function?tick()?{
??????savedCallback.current();??????????
????}
????if?(delay?!==?null)?{
??????let?id?=?setInterval(tick,?delay);????????
??????return?()?=>?clearInterval(id);
????}
??},?[delay]);
}

使用

useInterval(()?=>?{
??//?...
},?1000);?

這里每1000ms就會(huì)調(diào)用一次回調(diào)函數(shù),實(shí)現(xiàn)了定時(shí)執(zhí)行指定函數(shù)的功能。 有任何問題歡迎留言討論學(xué)習(xí)


react之自定義hooks的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
田阳县| 老河口市| 西充县| 英德市| 鄂尔多斯市| 冷水江市| 太仓市| 苏州市| 绍兴县| 微山县| 荆门市| 罗城| 体育| 太仓市| 合山市| 云和县| 墨竹工卡县| 龙里县| 昌邑市| 海宁市| 星子县| 大埔区| 金川县| 洪雅县| 古蔺县| 浦县| 洪湖市| 武穴市| 浏阳市| 社旗县| 大丰市| 时尚| 石河子市| 霍州市| 乌苏市| 东乡| 甘谷县| 百色市| 镇康县| 满洲里市| 施甸县|