最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React?useEffect不支持async?function示例分析

 更新時(shí)間:2022年07月11日 10:28:49   作者:葡萄zi  
這篇文章主要為大家介紹了React?useEffect不支持async?function示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

useEffect相比大家都耳熟能詳啦,如下這種寫(xiě)法,應(yīng)該是非常常見(jiàn)的需求。

useEffect(async () => {
   await getPoiInfo(); // 請(qǐng)求數(shù)據(jù)
}, []);

但是 React 本身并不支持這么做,理由是 effect function 應(yīng)該返回一個(gè)銷(xiāo)毀函數(shù)(effect:是指return返回的cleanup函數(shù)),如果 useEffect 第一個(gè)參數(shù)傳入 async,返回值則變成了 Promise,會(huì)導(dǎo)致 react 在調(diào)用銷(xiāo)毀函數(shù)的時(shí)候報(bào)錯(cuò) :function.apply is undefined。

React為什么這么設(shè)計(jì)呢?

1、useEffect 的返回值是要在卸載組件時(shí)調(diào)用的,React 需要在 mount 的時(shí)候馬上拿到這個(gè)值,不然就亂套了

2、useEffect() 可能有個(gè)潛在邏輯:第二次觸發(fā) useEffect 里的回調(diào)前,前一次觸發(fā)的行為都執(zhí)行完成,返回的清理函數(shù)也執(zhí)行完成。這樣邏輯才清楚。而如果是異步的,情況會(huì)變得很復(fù)雜,可能會(huì)很容易寫(xiě)出有 bug 的代碼。

下面有兩種改進(jìn)的方法大家可以參考下:

簡(jiǎn)單改造

1、簡(jiǎn)單改造的寫(xiě)法(不推薦)

第一種 在內(nèi)部創(chuàng)建一個(gè)異步函數(shù)anyNameFunction,等待他的結(jié)果,然后調(diào)用setData

但是這種方式存在一個(gè)問(wèn)題,如果asyncFunction請(qǐng)求有依賴(lài)外部的參數(shù),如果不更新requestData 的 effect 的依賴(lài),effect 就不會(huì)同步 props 和 state 帶來(lái)的變更,也就不回重新請(qǐng)求數(shù)據(jù)

useEffect(() => {
    // Create an scoped async function in the hook
    // 注意如果函數(shù)沒(méi)有使用組件內(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寫(xiě)法( Immediately Invoked Function Expression即立即調(diào)用的函數(shù)式表達(dá)式)

useEffect(() => {
  // Using an IIFE
  (async function anyNameFunction() {
    await requestData();
  })();
}, []);

2、把異步提取成單獨(dú)函數(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ì)上是添加了一層依賴(lài)檢查,使用useCallback,函數(shù)完全可以參與到數(shù)據(jù)流中,可以說(shuō)如果一個(gè)函數(shù)的輸入改變了,這個(gè)函數(shù)就改變了,如果沒(méi)有,函數(shù)也不會(huì)改變。

下面的例子中會(huì)依賴(lài) type ,如果 type 保持不變,requestData 也會(huì)保持不變,effect 也不會(huì)重新運(yùn)行,但是如果 type 修改了,requestData 也會(huì)隨之改變,因此會(huì)重新請(qǐng)求數(shù)據(jù)。

// 封裝
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]);
// 單獨(dú)處理外層刷新的接口請(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]);

關(guān)于為什么不支持異步的原理可以看下這篇文章里通過(guò)源碼的分析:useEffect 中為啥不能使用 async

有任何疑問(wèn)歡迎評(píng)論溝通,我會(huì)繼續(xù)更新!

其他相關(guān)文檔:

https://heptaluan.github.io/2020/11/07/React/17/

https://www.robinwieruch.de/react-hooks-fetch-data/

以上就是React useEffect不支持async function示例分析的詳細(xì)內(nèi)容,更多關(guān)于useEffect不支持async function的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React替換傳統(tǒng)拷貝方法的Immutable使用

    React替換傳統(tǒng)拷貝方法的Immutable使用

    Immutable.js出自Facebook,是最流行的不可變數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)之一。它實(shí)現(xiàn)了完全的持久化數(shù)據(jù)結(jié)構(gòu),使用結(jié)構(gòu)共享。所有的更新操作都會(huì)返回新的值,但是在內(nèi)部結(jié)構(gòu)是共享的,來(lái)減少內(nèi)存占用
    2023-02-02
  • React服務(wù)端渲染和同構(gòu)的實(shí)現(xiàn)

    React服務(wù)端渲染和同構(gòu)的實(shí)現(xiàn)

    本文主要介紹了React服務(wù)端渲染和同構(gòu)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • React Hooks的深入理解與使用

    React Hooks的深入理解與使用

    這篇文章主要介紹了React Hooks的深入理解與使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • React聲明組件的方法總結(jié)

    React聲明組件的方法總結(jié)

    這篇文章主要給大家介紹了react聲明組件有哪幾種方法,各有什么不同,文章通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-11-11
  • React函數(shù)式組件的性能優(yōu)化思路詳解

    React函數(shù)式組件的性能優(yōu)化思路詳解

    這篇文章主要介紹了React函數(shù)式組件的性能優(yōu)化思路詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • antd?upload上傳如何獲取文件寬高

    antd?upload上傳如何獲取文件寬高

    這篇文章主要介紹了antd?upload上傳如何獲取文件寬高問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • react項(xiàng)目自行配置熱更新的實(shí)現(xiàn)

    react項(xiàng)目自行配置熱更新的實(shí)現(xiàn)

    本文主要介紹了react項(xiàng)目自行配置熱更新的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11
  • React 封裝自定義組件的操作方法

    React 封裝自定義組件的操作方法

    React中自定義組件的重要性在于它們提供了代碼重用、降低耦合性、提升可維護(hù)性、更好的團(tuán)隊(duì)協(xié)作、靈活性和易于測(cè)試和調(diào)試等好處,從而提高了開(kāi)發(fā)效率和質(zhì)量,這篇文章主要介紹了React 封裝自定義組件,需要的朋友可以參考下
    2023-12-12
  • Parcel 打包示例(React HelloWorld)

    Parcel 打包示例(React HelloWorld)

    本篇文章主要介紹了Parcel 打包示例(React HelloWorld),詳細(xì)的介紹了Parcel打包的特點(diǎn)和使用示例,有興趣的可以了解一下
    2018-01-01
  • jsoneditor二次封裝實(shí)時(shí)預(yù)覽json編輯器組件react版

    jsoneditor二次封裝實(shí)時(shí)預(yù)覽json編輯器組件react版

    這篇文章主要為大家介紹了jsoneditor二次封裝實(shí)時(shí)預(yù)覽json編輯器組件react版示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10

最新評(píng)論

铜山县| 防城港市| 江都市| 万宁市| 黄平县| 宜兰县| 盈江县| 舒兰市| 汝阳县| 南丰县| 揭阳市| 丰原市| 新干县| 长阳| 张家港市| 疏附县| 东光县| 石嘴山市| 蒲城县| 蛟河市| 三原县| 县级市| 临潭县| 陆川县| 宿迁市| 科技| 乌拉特后旗| 万安县| 东乡族自治县| 台中县| 富阳市| 习水县| 常熟市| 信丰县| 都安| 三明市| 和平县| 黑龙江省| 盐亭县| 宜丰县| 皋兰县|