自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為什么useEffect不適合進(jìn)行API調(diào)用

譯文 精選
開發(fā)
對useEffects進(jìn)行API調(diào)用可能很容易出錯(cuò)或非常慢

  作者丨Rojan Maharjan

  譯者 | 涂承燁

  React團(tuán)隊(duì)在useEffect鉤子中做出的設(shè)計(jì)選擇仍然是一個(gè)熱議的話題。有些人喜歡,有些人不喜歡。

  如果你不是來自React世界,這聽起來肯定很奇怪,因?yàn)樗哪J(rèn)行為是非常容易遇到的可怕的“無限渲染循環(huán)”。例如:

useEffect(()=>{console.log("Hello World")})

       看起來很好,對吧?

  不,這將在每次渲染中打印“Hello World”,React dev模式下強(qiáng)迫癥的我會(huì)迫不及待地將結(jié)果放置到第二個(gè)參數(shù)的依賴數(shù)組中,像這樣:

useEffect(()=>{console.log("Hello World")},[])

因此,我們必須始終手動(dòng)確保每次使用它時(shí)不會(huì)陷入無限循環(huán)。

  就這樣,我們修復(fù)了這個(gè)問題,上面的代碼應(yīng)該只運(yùn)行一次,對嗎?

  技術(shù)上來說,但并不總是如此……

嚴(yán)格模式問題

  在開發(fā)模式下,如果你想享受React嚴(yán)格模式的好處,這實(shí)際上會(huì)被調(diào)用兩次。你已經(jīng)知道為什么這是一個(gè)問題了。以下面的代碼為例:

useEffect(()=>{
api.post("/view",{})
},[])

  假設(shè)我們有一個(gè)代碼,它發(fā)送一個(gè)事件,說用戶像上面的useEffect一樣查看了頁面。在嚴(yán)格模式下,React將運(yùn)行這個(gè)效果兩次,并發(fā)送一個(gè)雙重事件。

  你可以讓hacky參考下面這樣來工作:

export default function useEffectOnce(fn: () => void) {
const ref = useRef(false);
useEffect(() => {
if (ref.current) {
fn();
}
return () => {
ref.current = true;
};
}, [fn]);
}

  但從本質(zhì)上說,這是一個(gè)問題,至少不是一個(gè)優(yōu)雅的解決方案。

性能問題

  根據(jù)官方文檔,useEffect鉤子在整個(gè)UI或組件渲染完成后運(yùn)行。因此,當(dāng)我們在其中放入一個(gè)API調(diào)用時(shí),API調(diào)用將在UI完成完整呈現(xiàn)后啟動(dòng),如下所示:

圖片

  這并不是最優(yōu)的,因?yàn)楸M管react是快速的,但渲染UI總是會(huì)消耗一些時(shí)間,它將延遲我們的API調(diào)用,而這也可以在渲染開始時(shí)運(yùn)行。

  因此,更好的方法是獲取數(shù)據(jù)且并行渲染它。

  我們該怎么做呢?

React查詢來解決

  React query和我們討論的完全一樣,像useQuery這樣的鉤子會(huì)在渲染開始時(shí)立即獲取數(shù)據(jù),所以你不必等待React加載完整個(gè)組件,如下所示:

圖片

下面是一個(gè)例子:

// with react query
const { status, data, error, isFetching } = useQuery(
['data'],
async () => {
const data = await (
await fetch(`${API_BASE_URL}/data`)
).json()
return data
}
)// without react query
useEffect(() => {
try {
setLoading(true)(async () => {
const data = await (await fetch(`${API_BASE_URL}/data`)).json();
setData(data);
})();
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
}, []);

  通過查看語法,我們可以看到react query不僅在頁面加載時(shí)立即執(zhí)行query,而且還在react query返回的單個(gè)對象中處理許多事情,如加載狀態(tài)、錯(cuò)誤狀態(tài)和實(shí)際數(shù)據(jù)。

  此外,重新運(yùn)行/使查詢無效很簡單,如下所示。

queryClient.invalidateQueries(['data'])

其他一些著名的庫也解決了這些問題,如SWR、URQL和Apollo Client。

  解決該問題的另一種方法是執(zhí)行SSR,以便數(shù)據(jù)先在后端渲染,或者使用react-router 加載器等功能。

結(jié)論

  對useEffects進(jìn)行API調(diào)用可能很容易出錯(cuò)或非常慢。所以,除非不得已,否則最好避免使用。同時(shí),建議你通過一些庫來處理數(shù)據(jù)的獲取更為合適。

譯者簡介

  涂承燁,51CTO社區(qū)編輯,信息系統(tǒng)項(xiàng)目管理師、信息系統(tǒng)監(jiān)理師、PMP,某省綜合性評標(biāo)專家,擁有15年的開發(fā)經(jīng)驗(yàn)。對項(xiàng)目管理、前后端開發(fā)、微服務(wù)、架構(gòu)設(shè)計(jì)、物聯(lián)網(wǎng)、大數(shù)據(jù)等較為關(guān)注。

  原文鏈接:??https://articles.wesionary.team/why-useeffect-is-a-bad-place-to-make-api-calls-98a606735c1c??

責(zé)任編輯:張潔 來源: 51CTO技術(shù)棧
相關(guān)推薦

2021-01-31 18:52:36

Rust開發(fā)Web API

2024-10-06 13:00:05

2009-01-08 17:15:29

服務(wù)器虛擬化高性能計(jì)算

2012-06-25 14:09:58

2010-01-08 09:13:28

2018-03-27 10:52:59

程序員不適合C++

2022-07-12 14:04:19

Kafka

2013-08-16 10:00:45

VMwareOpenStack

2018-07-17 10:16:33

Arch Linux服務(wù)器操作系統(tǒng)

2015-03-12 13:39:48

Hadoop場景大數(shù)據(jù)

2019-08-29 10:33:52

開發(fā)技能代碼

2009-01-15 18:30:11

服務(wù)器虛擬化VMware

2018-07-29 07:58:34

物聯(lián)網(wǎng)IOT物聯(lián)網(wǎng)產(chǎn)品

2010-07-20 09:56:53

VDI部署

2012-03-13 15:28:47

Kindle Fire傲游

2013-08-13 14:33:17

程序員

2013-12-09 10:16:03

Android firAndroid開發(fā)移動(dòng)創(chuàng)業(yè)

2016-11-04 09:41:48

容器Docker

2019-08-26 00:37:19

WiFi 65GWi-Fi

2015-07-23 11:26:35

虛擬化負(fù)載類型
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號