新聞中心
大家好,我是卡頌。

在貴定等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都做網(wǎng)站、網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需開發(fā)網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),營銷型網(wǎng)站,外貿(mào)營銷網(wǎng)站建設(shè),貴定網(wǎng)站建設(shè)費(fèi)用合理。
都說Hooks是React的未來,但Hooks的最佳實(shí)踐是什么呢?
關(guān)于這塊知識,官方文檔一點(diǎn)兒都沒提及。
所以在實(shí)際項(xiàng)目中,常會(huì)出現(xiàn)類似下面的問題:
- // ...
- useEffect(() => {
- fetchData(a, b).then(
- // ...
- )
- }, [a, b])
- //...
useEffect依賴了a b兩個(gè)狀態(tài),當(dāng)其中任意一個(gè)變化后會(huì)執(zhí)行fetchData請求數(shù)據(jù)。
當(dāng)應(yīng)用變得復(fù)雜,要追蹤a、b何時(shí)變化變得越來越難。
假以時(shí)日接口調(diào)整,fetchData還需要狀態(tài)c作為參數(shù)。那么追蹤狀態(tài)變化的難度又會(huì)進(jìn)一步提高。
最終會(huì)導(dǎo)致:
- 輕則無意義的fetchData多次調(diào)用
- 重則邏輯出現(xiàn)難以追查的bug
有朋友會(huì)說:你可以封裝自定義Hook啊。
這只是將問題隱藏的更深了......
如何解決這個(gè)問題
以上問題的本質(zhì)原因是:「副作用」實(shí)在太多,可以被當(dāng)作「副作用」的東西也實(shí)在太多。這導(dǎo)致useEffect被濫用。
所以,要解決濫用問題,就需要為不同類型「副作用」提供官方解決方案。
這樣,具體問題有了具體解決方案,才不會(huì)useEffect一把梭。
從一個(gè)PR看到變化
最近React有個(gè)很不起眼的PR[1]:
大體意思是:
在之前,當(dāng)你在一個(gè)已經(jīng)卸載的組件(unmounted)中調(diào)用setState會(huì)觸發(fā)一個(gè)warning,這個(gè)PR將移除這個(gè)warning。
舉個(gè)例子,以下代碼在組件mount時(shí)注冊handleChange:
- useEffect(() => {
- function handleChange() {
- setState(store.getState())
- }
- store.subscribe(handleChange)
- return () => store.unsubscribe(handleChange)
- }, [])
如果你忘記寫這行解綁代碼:
- return () => store.unsubscribe(handleChange)
那么組件卸載后handleChange也可能被調(diào)用,進(jìn)而調(diào)用setState。
這是潛在的內(nèi)存泄漏。
在之前的React中,這種行為會(huì)報(bào)warning。
那為什么要移除這種行為下的warning呢?
PR的背后
一方面,這個(gè)warning有一定概率誤判,比如「點(diǎn)擊按鈕提交表單」:
- async function handleSubmit() {
- setPending(true)
- await post('/someapi')
- setPending(false)
- }
點(diǎn)擊按鈕后調(diào)用setPending觸發(fā)loading圖標(biāo)顯示,接著發(fā)起post請求。
有可能請求返回前組件就卸載了,此時(shí)會(huì)調(diào)用:
- setPending(false)
并不會(huì)有內(nèi)存泄漏風(fēng)險(xiǎn),但是會(huì)報(bào)warning。
不過warning移除還有另一個(gè)更本質(zhì)的原因:
在第一個(gè)示例中,我們在useEffect中調(diào)用store.subscribe,這種行為可以歸類為:
在組件中訂閱外部源
什么是「外部源」呢?
任何「變化與否不受React控制的源」都是「外部源」。
比如:
- 各種第三方狀態(tài)管理庫
- 希望location.hash變化觸發(fā)組件更新
未來所有這類行為都會(huì)收斂到useMutableSource這個(gè)Hook中。
更多例子
再比如,對于I/O操作(比如「請求數(shù)據(jù)」)這種大家都會(huì)放在useEffect中的邏輯,未來使用resource結(jié)合Suspense可能是更好的選擇:
- const resource = fetchDetail();
- function Page() {
- return (
Loading...}> - );
- }
- function Details() {
- const data = resource.read();
- return
{data.name}
;- }
以上例子中,調(diào)用fetchDetail會(huì)發(fā)起數(shù)據(jù)請求。
Details組件調(diào)用resource.read直接消費(fèi)數(shù)據(jù)即可。
如果數(shù)據(jù)還未返回,視圖會(huì)渲染最近的Suspense的fallback(即
Loading...
)。總結(jié)
「副作用」是多種多樣的,以前沒得選,只能用useEffect。
隨著React18的穩(wěn)定,面對不同「副作用」場景,會(huì)有更明確的解決方案。
屆時(shí),可能才最終迎來Hooks真香的時(shí)代......
文章題目:從一個(gè)PR窺探React未來開發(fā)方式
文章URL:http://m.fisionsoft.com.cn/article/dhghhcs.html


咨詢
建站咨詢
