useEffect是很常見的,現(xiàn)在寫的是十分需求的。
useEffect(async()=>{ awaitgetPoiInfo();//請(qǐng)求數(shù)據(jù) },[]);
可是React 卻無(wú)法支持這樣做,就是因?yàn)?effect function 應(yīng)該返回一個(gè)銷毀函數(shù)(effect:是指return返回的cleanup函數(shù)),如果 useEffect 第一個(gè)參數(shù)傳入 async,返回值則變成了 Promise,會(huì)導(dǎo)致 react 在調(diào)用銷毀函數(shù)的時(shí)候報(bào)錯(cuò) :function.apply is undefined。
React為什么這么設(shè)計(jì)呢?
1、useEffect 的返回值是要在卸載組件時(shí)調(diào)用的,React 需要在 mount 的這樣才可以獲取值。
2、useEffect() 似乎有個(gè)潛在邏輯:第二次觸發(fā) useEffect 里的回調(diào)前,前一次觸發(fā)的行為都執(zhí)行完成,返回的清理函數(shù)也執(zhí)行完成。這樣邏輯才清楚。而如果是異步的,情況會(huì)變得很復(fù)雜,可能會(huì)很容易寫出有 bug 的代碼。
下面有兩種改進(jìn)的方法大家可以參考下:
簡(jiǎn)單改造
1、簡(jiǎn)單改造的寫法(不推薦)
第一種 在內(nèi)部創(chuàng)建一個(gè)異步函數(shù)anyNameFunction,之后就是等待,在后來(lái)就是調(diào)用setData
可也有一個(gè)問(wèn)題要知道,就是在asyncFunction請(qǐng)求有依賴外部的參數(shù),不更新requestData 的 effect 的依賴,effect 就不會(huì)同步 props 和 state 帶來(lái)的變更,也就不回重新請(qǐng)求數(shù)據(jù)
useEffect(() => { // Create an scoped async function in the hook // 注意如果函數(shù)沒有使用組件內(nèi)的任何值,可以把它提到組件外面去定義 // 下面代碼可以提到外面,可以自由地在 effect 中使用,下面就不改啦 async function asyncFunction() { await requestData(); setData(data) } // Execute the created function directly anyNameFunction(); }, []); // 這里設(shè)置成[]數(shù)組,因?yàn)槲覀冎幌朐趻燧d的時(shí)候運(yùn)行它一次
或者 useEffect中異步函數(shù)采用IIFE寫法( Immediately Invoked Function Expression即立即調(diào)用的函數(shù)式表達(dá)式)
useEffect(() => { // Using an IIFE (async function anyNameFunction() { await requestData(); })(); }, []);
2、把異步提取成多帶帶函數(shù)或自定義hook(推薦)
第一種自定義 hook包裹,然后再effect中通過(guò)promise.then調(diào)用(github上大佬給的答案:github)
// 自定義hook function useAsyncEffect(effect: () => Promise<void | (() => void)>, dependencies?: any[]) { return useEffect(() => { const cleanupPromise = effect() return () => { cleanupPromise.then(cleanup => cleanup && cleanup()) } }, dependencies) } // 使用 useAsyncEffect(async () => { const count = await fetchData() setCount(count) }, [fetchData])
或者利用useCallback 包裝成hook
useCallback 本質(zhì)上是添加了一層依賴檢查,使用useCallback,函數(shù)完全可以參與到數(shù)據(jù)流中,可以說(shuō)如果一個(gè)函數(shù)的輸入改變了,這個(gè)函數(shù)就改變了,如果沒有,函數(shù)也不會(huì)改變。
下面的例子中會(huì)依賴 type ,如果 type 保持不變,requestData 也會(huì)保持不變,effect 也不會(huì)重新運(yùn)行,但是如果 type 修改了,requestData 也會(huì)隨之改變,因此會(huì)重新請(qǐng)求數(shù)據(jù)?!?/p>
// 封裝 const requestData = useCallback(async () => { changeLoading(true); changeError(false); changeList([]); requestAPI.getFeature({ type }).then((data) => { if (data) { changeList(data); } }).catch((e) => { changeError(true); }).finally(() => { changeLoading(false); }); }, [type]); // type改變會(huì)重新生成函數(shù) // 普通接口請(qǐng)求 useEffect(() => { requestData(); }, [requestData]); // 多帶帶處理外層刷新的接口請(qǐng)求 // refreshing是props傳遞的過(guò)來(lái)的,不應(yīng)該與state狀態(tài)改變混在一起,這也是hook的優(yōu)勢(shì),將不相關(guān)的狀態(tài)邏輯拆分成更細(xì)粒度 useEffect(() => { if (!refreshing) { return; } requestData().then(() => { getRefreshStatus(false); }); }, [refreshing]);
今天講到這里,后面更多精彩內(nèi)容歡迎觀看。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/128370.html
摘要:現(xiàn)在,請(qǐng)求數(shù)據(jù)和查詢參數(shù)兩個(gè)相互獨(dú)立,但是我們需要像一個(gè)辦法希望他們耦合起來(lái),只獲取輸入框輸入的參數(shù)指定的話題文章。好了,現(xiàn)在一旦你改變輸入框內(nèi)容,數(shù)據(jù)就會(huì)重新獲取。 showImg(https://segmentfault.com/img/remote/1460000018652592?w=1024&h=683); 通過(guò)這個(gè)教程,我想告訴你在 React 中如何使用 state 和 ...
摘要:到目前為止,表達(dá)這種流程的基本形式是課程。按鈕依次響應(yīng)并更改獲取更新的文本。事實(shí)證明不能從返回一個(gè)??梢栽诮M件中使用本地狀態(tài),而無(wú)需使用類。替換了提供統(tǒng)一,和。另一方面,跟蹤中的狀態(tài)變化確實(shí)很難。 備注:為了保證的可讀性,本文采用意譯而非直譯。 在這個(gè) React鉤子 教程中,你將學(xué)習(xí)如何使用 React鉤子,它們是什么,以及我們?yōu)槭裁催@樣做! showImg(https://segm...
背景 在使用useEffect中用啦回調(diào)函數(shù)中使用 async...await... 這時(shí)候就會(huì)報(bào)錯(cuò)。 上面代碼可以看到,在報(bào)錯(cuò),effect function 應(yīng)該返回一個(gè)銷毀函數(shù)(effect:是指return返回的cleanup函數(shù)),如果 useEffect 第一個(gè)參數(shù)傳入 async,返回值則變成了 Promise,結(jié)果就是會(huì)導(dǎo)致 react 在調(diào)用銷毀函數(shù)的時(shí)候報(bào)錯(cuò)。 React...
摘要:首先,我們需要一個(gè)基本框架來(lái)處理表單域變化和表格提交。最起碼我們需要提供一個(gè)來(lái)告訴如果用戶還沒有對(duì)表單域進(jìn)行改動(dòng),就不必展示錯(cuò)誤。我們需要一個(gè)來(lái)標(biāo)識(shí)用戶已嘗試提交表單,還需要來(lái)標(biāo)識(shí)表單是否正在提交以及每個(gè)表單域是否正在進(jìn)行異步校驗(yàn)。 showImg(https://segmentfault.com/img/remote/1460000017516912?w=1200&h=630); ...
摘要:在這種情況下,如果狀態(tài)發(fā)生變化,將再次運(yùn)行以從獲取數(shù)據(jù)。你可以在內(nèi)做到在表單中獲取數(shù)據(jù)到目前為止,我們只有和按鈕的組合?,F(xiàn)在,在獲取數(shù)據(jù)時(shí),可以使用向函數(shù)發(fā)送信息。例如,在成功請(qǐng)求的情況下,用于設(shè)置新狀態(tài)對(duì)象的數(shù)據(jù)。 原文鏈接: https://www.robinwieruch.de/r... 在本教程中,我想通過(guò)state和effect hook來(lái)像你展示如何用React Hook...
閱讀 596·2023-03-27 18:33
閱讀 790·2023-03-26 17:27
閱讀 684·2023-03-26 17:14
閱讀 645·2023-03-17 21:13
閱讀 573·2023-03-17 08:28
閱讀 1895·2023-02-27 22:32
閱讀 1377·2023-02-27 22:27
閱讀 2280·2023-01-20 08:28