欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React之如何在Suspense中優(yōu)雅地請求數(shù)據(jù)

 更新時間:2023年04月25日 09:13:42   作者:LunaSeki  
Suspense 是 React 中的一個組件,直譯過來有懸掛的意思,能夠?qū)⑵浒漠惒浇M件掛起,直到組件加載完成后再渲染,本文詳細介紹了如何在Suspense中請求數(shù)據(jù),感興趣的小伙伴可以參考閱讀本文

什么是 Sunpense

Suspense 是 React 中的一個組件,直譯過來有懸掛的意思,能夠?qū)⑵浒?strong>異步組件掛起,直到組件加載完成后再渲染

懶加載

在 React 組件掛載的過程中,一般是等所有的組件都加載好后一起掛載到 Dom 上, 如果出現(xiàn)了較大的組件,就會拖慢網(wǎng)頁整體的加載速度,特別是在 SPA 上會出現(xiàn)長時間的白屏,影響用戶體驗

于是,React 提供了lazy Api,用于延遲加載某個組件,這樣就不會拖慢其他組件的加載速度

給 React 上的 lazy 方法傳入一個返回 Promise 或類 Promise 對象的函數(shù),即可實現(xiàn)對 Promise 的結(jié)果的懶加載

恰好,ES 中的動態(tài)引入import()就會返回一個 Promise,因此我們可將其寫成匿名函數(shù)的返回值,并作為參數(shù)傳給lazy,下面代碼就對組件進行了懶加載

// 對Component進javascript行懶加載
const LazyComponent = React.lazy(() => import("./Component"));

掛起

但是通過lazy得出的組件直接使用的話會在加載時報錯,還需要在外面包裹一層 Suspense 組件才能夠正常使用

// 懶加的載子組件
const SubComponent = React.lazy(() => import("./SubComponent"));

// 用Suspense包裹的組件會被掛起,加載完成后再掛載
function MainComponent() {
	return <Suspense fallback={<div>Loading......</div>}>
        <SubComponent>
    </Suspense>;
}

渲染時,React 會先將 Suspense 的 fallback 中的內(nèi)容掛載,并將子組件掛起,等待加載完成后就掛載,并將 fallback 卸載 例如上面的代碼,會在 SubComponent 加載時顯示 Loading......,等待 Subcomponent 加載完成后顯示子組件內(nèi)容

懶加載組件的加載過程

為啥直接使用會懶加載的組件報錯呢?我們輸出一下lazy返回的對象看看:

原來這個對象并不是我們熟悉的組件,而是擁有狀態(tài)(status)和結(jié)果(result)的高階對象,直接使用當然會報錯啦

那么問題來了,React 為什么要返回這個對象而不是返回一個普通的組件呢?

這是為了通知 Suspense 組件!

簡單地說,Suspense 組件會嘗試渲染子組件,假如子組件未加載完成,則會轉(zhuǎn)而渲染 fallback 里的內(nèi)容

那么 Suspense 又是如何判斷子組件是否加載完成的呢?對了,就是通過捕獲子組件異常!

子組件有三種狀態(tài):

  • 加載中,拋出加載中的 Promise
  • 加載完成,正常返回結(jié)果
  • 加載異常,拋出錯誤

Suspense 會嘗試加載子組件,并通componentDidCatch過對拋出的異常進行捕獲,大概加載流程為:

這樣,通過對未加載完成的子組件不斷嘗試加載,就能夠?qū)崿F(xiàn)“掛起”這一過程

對需要請求數(shù)據(jù)的組件使用 Suspense

現(xiàn)在我們知道,需要將子組件加載的狀態(tài)通知 Suspense 才能夠?qū)?strong>等待 ajax 請求后再加載組件的效果,所以普通使用 ajax 發(fā)起請求是無法做到的

react-cache

react-cache 是 React 官方的處理數(shù)據(jù)副作用方案,里面提供了一個方法unstable_createResource,用于創(chuàng)建一個類似懶加載組件的對象

你可以訪問這個對象上的read方法,若訪問的數(shù)據(jù)不存在,則動態(tài)加載,并拋出 Promise,若數(shù)據(jù)存在,則正常返回數(shù)據(jù)。聽起來是不是和懶加載很像?

import getURL from "./api"; //一個封裝的請求,返回一個Promise
import { unstable_createResource } from "react-cache";

// 類似import(),傳入一個返回值為PRomise的函數(shù),生成一個擁有狀態(tài)的對象
const myData = unstable_createResource(() => {
	getURL();
});
// 在子組件中使用
function SubComponent() {
	const data = myData.read();
	return <div>{data}</div>;
}

這樣,父組件中包裹子組件的 Suspense 就能像檢測懶加載組件一樣檢測子組件數(shù)據(jù)加載的狀態(tài),從而展示 fallback 或子組件了

但是,react-cache 其實是一種數(shù)據(jù)緩存方案,使用 LRU(當緩存空間滿時,優(yōu)先清理最近最少使用的數(shù)據(jù))策略緩存數(shù)據(jù),能夠根據(jù)不同的參數(shù)緩存請求的結(jié)果,并供組件調(diào)用,如下

import getURL from "./api";
import { unstable_createResource } from "react-cache";

const myData = unstable_createResource(
	(param1, param2) => {
		getURL(param1, param2);
	},
	(param1, param2) => param1 + param2
);

unstable_createResource接受了兩個參數(shù)

  • 第一個是產(chǎn)生 Promise 的函數(shù),可以將參數(shù)傳入匿名函數(shù)后再傳入請求數(shù)據(jù)的函數(shù)(有點套娃,但是這樣傳參方便了函數(shù)內(nèi)部復用請求)
  • 第二個參數(shù)是個哈希函數(shù),作用是接受與前面函數(shù)同樣的參數(shù),然后生成一串識別碼給函數(shù)本身查詢數(shù)據(jù)是否存在(緩存)

這樣,使用時就能read方法傳遞不同的參數(shù),對于緩存一些高頻使用的接口的數(shù)據(jù)非常有用

如果你只是想初始化時請求、不想使用緩存,或者單純的不想引入更多庫,那么可以手寫一個能夠通知 Suspense的函數(shù)

自己寫一個加工函數(shù)

從上面兩個例子可以知道,要通知 Suspense 函數(shù),則必須要根據(jù) Promise 狀態(tài)進行不同的操作

為了簡化,我們的加工函數(shù)就不自己創(chuàng)建 Promise 了,而是在外面創(chuàng)建后對 Promise 進行加工

// 創(chuàng)建函數(shù),接受一個promise
function wrapPromise(promise) {
	let status = 0;
	let result;
	// 調(diào)用promise,并在回調(diào)中更改加工函數(shù)中的狀態(tài)
	const callPromise = promise.then(
		(res) => {
			status = 1;
			result = res;
		},
		(err) => {
			status = -1;
			result = err;
		}
	);
	// 返回一個對象,只需要提供read方法
	return {
		read() {
			switch (status) {
				case 0:
					throw callPromise;
				case 1:
					return result;
				case -1:
					throw result;
			}
		},
	};
}

這樣,子組件通過調(diào)用加工函數(shù)返回的對象上的read方法,即可根據(jù)請求的狀態(tài)優(yōu)雅地加載組件了

// 獲取加工后的對象
const data = wrapPromise(promise);

// 在子組件中使用
function SubComponent() {
	const data = myData.read();
	return <div>{data}</div>;
}

請求數(shù)據(jù)的時機

有了 Suspense 和加工函數(shù),我們還要知道該在什么地方調(diào)用加工函數(shù)

  • 在子組件中調(diào)用warpPromise然后請求?

    這是不行的,因為 Suspense 更改渲染的組件時會進行組件的重新掛載操作,相當于子組件中的所有操作都重新運行一遍。 重新運行的加工函數(shù)又會重新調(diào)用 Promise 并返回全新的對象,里面的read方法也會繼續(xù)拋出錯誤,從而使得 Suspense 一直渲染 fallback 中的內(nèi)容

  • 在文件最外層調(diào)用?

    這是可行的,組件內(nèi)可以正常訪問到外面的數(shù)據(jù)。但是數(shù)據(jù)寫死了不太好控制,只能夠做一些初始化請求

  • 在父組件中調(diào)用?

    在父組件中調(diào)用,然后通過 prop 傳遞給子組件,這是可行的。并且還可以結(jié)合其他 Hook,進行靈活地操作

結(jié)論

要優(yōu)雅地在 Suspense 中請求數(shù)據(jù),其實只要實現(xiàn)通過拋出異常通知 Suspense 即可

實際開發(fā)中通過 promise.then 直接操控自定義的加載遮罩也比較常見,也不必強行使用 Suspense

但是如果需要對數(shù)據(jù)進行緩存,那么在使用 react-cache 時順手用上 Suspense 就更方便了

到此這篇關于React之如何在Suspense中優(yōu)雅地請求數(shù)據(jù)的文章就介紹到這了,更多相關在Suspense中請求數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • antd+react中upload手動上傳單限制上傳一張

    antd+react中upload手動上傳單限制上傳一張

    本文主要介紹了antd+react中upload手動上傳單限制上傳一張,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • React自定義Hook-useForkRef的具體使用

    React自定義Hook-useForkRef的具體使用

    本文主要介紹了React自定義Hook-useForkRef的具體使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • react使用axios進行api網(wǎng)絡請求的封裝方法詳解

    react使用axios進行api網(wǎng)絡請求的封裝方法詳解

    這篇文章主要為大家詳細介紹了react使用axios進行api網(wǎng)絡請求的封裝方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 使用react-beautiful-dnd實現(xiàn)列表間拖拽踩坑

    使用react-beautiful-dnd實現(xiàn)列表間拖拽踩坑

    相比于react-dnd,react-beautiful-dnd更適用于列表之間拖拽的場景,本文主要介紹了使用react-beautiful-dnd實現(xiàn)列表間拖拽踩坑,感興趣的可以了解一下
    2021-05-05
  • react-redux action傳參及多個state處理的實現(xiàn)

    react-redux action傳參及多個state處理的實現(xiàn)

    本文主要介紹了react-redux action傳參及多個state處理的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • React中的生命周期詳解

    React中的生命周期詳解

    這篇文章主要介紹了React中的生命周期,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-09-09
  • react將文件轉(zhuǎn)為base64上傳的示例代碼

    react將文件轉(zhuǎn)為base64上傳的示例代碼

    本文主要介紹了react將文件轉(zhuǎn)為base64上傳的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-09-09
  • React Native模塊之Permissions權限申請的實例相機

    React Native模塊之Permissions權限申請的實例相機

    這篇文章主要介紹了React Native模塊之Permissions權限申請的實例相機的相關資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • React如何配置src根目錄@

    React如何配置src根目錄@

    這篇文章主要介紹了React如何配置src根目錄@,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-01-01
  • React深入分析更新的創(chuàng)建源碼

    React深入分析更新的創(chuàng)建源碼

    React組件分為函數(shù)組件與class組件;函數(shù)組件是無狀態(tài)組件,class稱為類組件;函數(shù)組件只有props,沒有自己的私有數(shù)據(jù)和生命周期函數(shù);class組件有自己私有數(shù)據(jù)(this.state)和生命周期函數(shù)
    2023-01-01

最新評論