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

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)的高階對象,直接使用當(dāng)然會報錯啦

那么問題來了,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(當(dāng)緩存空間滿時,優(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)部復(fù)用請求)
  • 第二個參數(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 更改渲染的組件時會進行組件的重新掛載操作,相當(dāng)于子組件中的所有操作都重新運行一遍。 重新運行的加工函數(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 就更方便了

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

相關(guān)文章

  • React快速入門教程

    React快速入門教程

    本文主要介紹了React的相關(guān)知識,具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • React中classnames庫使用示例

    React中classnames庫使用示例

    這篇文章主要為大家介紹了React中classnames庫使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • 在React項目中使用iframe嵌入一個網(wǎng)站的步驟

    在React項目中使用iframe嵌入一個網(wǎng)站的步驟

    本文介紹了如何在React項目中通過iframe嵌入百度網(wǎng)站的步驟,首先創(chuàng)建一個Baidu.js組件,并在該組件中設(shè)置iframe來加載百度,然后在App.js中引入并使用Baidu組件,還討論了因安全策略可能無法加載某些網(wǎng)站的問題,需要的朋友可以參考下
    2024-09-09
  • React通過ref獲取子組件的數(shù)據(jù)和方法

    React通過ref獲取子組件的數(shù)據(jù)和方法

    這篇文章主要介紹了React如何通過ref獲取子組件的數(shù)據(jù)和方法,文中有詳細的總結(jié)內(nèi)容和代碼示例,具有一定的參考價值,需要的朋友可以參考下
    2023-10-10
  • 回顧Javascript React基礎(chǔ)

    回顧Javascript React基礎(chǔ)

    這篇文章主要介紹了Javascript React基礎(chǔ),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的同學(xué)可以參考一下
    2019-06-06
  • React?事件綁定的最佳實踐

    React?事件綁定的最佳實踐

    本文主要介紹了移動端點擊事件的300ms延遲問題,并詳細的介紹了三種解決方法,具有一定的參考價值,感興趣的可以了解一下
    2025-03-03
  • 使用React+ts實現(xiàn)無縫滾動的走馬燈詳細過程

    使用React+ts實現(xiàn)無縫滾動的走馬燈詳細過程

    這篇文章主要給大家介紹了關(guān)于使用React+ts實現(xiàn)無縫滾動的走馬燈詳細過程,文中給出了詳細的代碼示例以及圖文教程,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2023-08-08
  • React?Hooks?實現(xiàn)的中文輸入組件

    React?Hooks?實現(xiàn)的中文輸入組件

    這篇文章主要為大家介紹了React?Hooks實現(xiàn)的中文輸入組件示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • 詳解升級react-router 4 踩坑指南

    詳解升級react-router 4 踩坑指南

    本篇文章主要介紹了詳解升級react-router 4 踩坑指南,主要是對react-router 4升級的踩坑總結(jié),有興趣的可以了解一下
    2017-08-08
  • 關(guān)于react-router的幾種配置方式詳解

    關(guān)于react-router的幾種配置方式詳解

    本篇文章主要介紹了關(guān)于react-router的幾種配置方式詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07

最新評論

宣汉县| 方城县| 辽阳市| 济源市| 崇礼县| 乌拉特后旗| 资中县| 陕西省| 嘉定区| 庆安县| 沛县| 桃园市| 崇文区| 凤庆县| 格尔木市| 苏尼特左旗| 溧水县| 顺平县| 岫岩| 忻州市| 乌鲁木齐县| 博白县| 滨州市| 齐齐哈尔市| 岳阳县| 龙井市| 泰宁县| 集贤县| 阿克陶县| 尼木县| 宁津县| 杭锦旗| 宾川县| 定远县| 华阴市| 平武县| 辽阳县| 彭州市| 昔阳县| 双峰县| 龙胜|