作者丨Rojan Maharjan
譯者 | 涂承燁
React團(tuán)隊(duì)在useEffect鉤子中做出的設(shè)計(jì)選擇仍然是一個(gè)熱議的話題。有些人喜歡,有些人不喜歡。
如果你不是來自React世界,這聽起來肯定很奇怪,因?yàn)樗哪J(rèn)行為是非常容易遇到的可怕的“無限渲染循環(huán)”。例如:
看起來很好,對吧?
不,這將在每次渲染中打印“Hello World”,React dev模式下強(qiáng)迫癥的我會(huì)迫不及待地將結(jié)果放置到第二個(gè)參數(shù)的依賴數(shù)組中,像這樣:
因此,我們必須始終手動(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è)問題了。以下面的代碼為例:
假設(shè)我們有一個(gè)代碼,它發(fā)送一個(gè)事件,說用戶像上面的useEffect一樣查看了頁面。在嚴(yán)格模式下,React將運(yùn)行這個(gè)效果兩次,并發(fā)送一個(gè)雙重事件。
你可以讓hacky參考下面這樣來工作:
但從本質(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è)例子:
通過查看語法,我們可以看到react query不僅在頁面加載時(shí)立即執(zhí)行query,而且還在react query返回的單個(gè)對象中處理許多事情,如加載狀態(tài)、錯(cuò)誤狀態(tài)和實(shí)際數(shù)據(jù)。
此外,重新運(yùn)行/使查詢無效很簡單,如下所示。
其他一些著名的庫也解決了這些問題,如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??