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

React中Suspense及l(fā)azy()懶加載及代碼分割原理和使用方式

 更新時間:2022年09月15日 09:13:38   作者:何其濤  
這篇文章主要介紹了React中Suspense及l(fā)azy()懶加載及代碼分割原理和使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Suspense和lazy()都是react中比較新的特性,在項目中使用還比較少,但是學(xué)習(xí)一下有助于在后面的項目中使用,同樣可以一窺React未來的發(fā)展方向

React.lazy()

概括

顧名思義lazy()方法是用來對項目代碼進行分割,懶加載用的.只有當(dāng)組件被加載,內(nèi)部的資源才會導(dǎo)入

為什么需要懶加載

在React的項目中import導(dǎo)入其他組件和庫都是默認在初始直接導(dǎo)入的,webpack等打包工具會將import導(dǎo)入的文件直接合并到一個大文件中,如果項目很大,打包完后初始化加載時需要加載的文件會很大,這時候就需要代碼分割

官方文檔中的例子

項目中:

// app.js
import { add } from './math.js';
console.log(add(16, 26)); // 42
// math.js
export function add(a, b) {
? return a + b;
}

打包后

function add(a, b) {
? return a + b;
}
console.log(add(16, 26)); // 42

如何進行代碼分割

在你的應(yīng)用中引入代碼分割的最佳方式是通過動態(tài) import() 語法,這是官方文檔中說的

動態(tài)import例子:

靜態(tài)導(dǎo)入:

import { add } from './math';
console.log(add(16, 26));

動態(tài)導(dǎo)入:

import("./math").then(math => {
? console.log(math.add(16, 26));
});

使用了動態(tài)導(dǎo)入之后,webpack檢測到這種語法會自動代碼分割,也就是壓縮到兩個文件里

React.lazy()就是對這個種動態(tài)導(dǎo)入方式的優(yōu)化方法

使用:

const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
? return (
? ? // Displays <Spinner> until OtherComponent loads
? ? <React.Suspense fallback={<Spinner />}>
? ? ? <div>
? ? ? ? <OtherComponent />
? ? ? </div>
? ? </React.Suspense>
? );
}

發(fā)現(xiàn)沒有原來的動態(tài)導(dǎo)入寫法像 Promise的寫法鏈?zhǔn)秸{(diào)用,現(xiàn)在動態(tài)導(dǎo)入的方式,有點類似于Async寫出來是同步使用的,可以直接講返回的Promise對象作為組件使用,當(dāng)這個組件pending是顯示的是Suspense中fallback的內(nèi)容,只有resolve才顯示加載好的組件.

所以可以看出Suspense和React.lazy()需要結(jié)合在一起用,否則會報錯缺少Placeholder UI`

Suspense

Suspense的英文意思是懸念,懸停**,Suspense的作用就是在遇到異步請求或者異步導(dǎo)入組件的時候等待請求和導(dǎo)入完成再進行渲染,**相比普通的組件, 我們是要求render是一個純函數(shù),一旦開始渲染不會等待,而有了Suspense后我們可以再render過程中寫一部代碼.

Suspense應(yīng)用場景

Subspense存在兩種應(yīng)用場景,第一種就是動態(tài)導(dǎo)入組件(如上),一種就是異步請求數(shù)據(jù)(暫時不支持,大概16.9版本)

動態(tài)導(dǎo)入組件

動態(tài)導(dǎo)入組件上面的例子就是上面的代碼片段,就是當(dāng)這個組件pending是顯示的是Suspense中fallback的內(nèi)容,只有resolve才顯示加載好的組件,所以fallback不能為空

優(yōu)點

好處在于我們可以不用創(chuàng)建一些組件狀態(tài)的變量來控制是否顯示loading畫面和真正組件,這部分邏輯直接由Suspense內(nèi)部實現(xiàn). 而且還有一種場景就是當(dāng)一個父組件中,有多個動態(tài)加載的組件,Suspense可以直接將loading狀態(tài)聚合,只有當(dāng)所有組件加載完成才顯示,這里免去了復(fù)雜的邏輯判斷.

數(shù)據(jù)請求后渲染頁面

Suspense暫時還不支持數(shù)據(jù)請求后渲染, 預(yù)計是在16.9版本也就是2019年年中發(fā)布,但是以及有了實例使用的方法,下面這里就是官方的示例代碼,這里做一些翻譯解釋

// unstable_createResource這個就是一個封裝的請求數(shù)據(jù)的插件,不用太清楚類似于fetch
import {unstable_createResource} from 'react-cache';
// 聲明請求數(shù)據(jù)的方法
const TodoResource = unstable_createResource(fetchTodo);
//內(nèi)部請求TodoResource.read(props.id) 就是異步請求數(shù)據(jù)
function Todo(props) {
? // Suspends until the data is in the cache
? const todo = TodoResource.read(props.id);
? return <li>{todo.title}</li>;
}
function App() {
? return (
? ? // 只有當(dāng)兩個Todo內(nèi)部的異步請求都完成后才能渲染出來,否則渲染<Spinner/>
? ? <React.Suspense fallback={<Spinner />}>
? ? ? <ul>
? ? ? ? {/* Siblings fetch in parallel */}
? ? ? ? <Todo id="1" />
? ? ? ? <Todo id="2" />
? ? ? </ul>
? ? </React.Suspense>
? );
}

這就是Suspense請求數(shù)據(jù)時的使用的方法,同樣解決了loading狀態(tài)的問題,相當(dāng)于再render過程中加入了異步副作用操作,再普通的組件中異步操作是不起作用的,因為先渲染完,異步數(shù)據(jù)才會返回,這時候已經(jīng)渲染完了.

Suspense實現(xiàn)原理

Subspense的實現(xiàn)主要就是利用了**ComponentDidCatch這個生命周期,這個什么周期就是用來捕獲子組件樹中的任何Javascript異常**

源碼就不分析了,這里說一下大概的流程步驟:

  • 父組件渲染到子組件時發(fā)現(xiàn)異步請求,直接拋出錯誤,捕獲的結(jié)果是一個Promise對象
  • ComponentDidCatch捕獲這個Promise對象,pending狀態(tài)下渲染fallback的
  • 當(dāng)resolve時重新render,遇到下一個異步請求重復(fù)上面操作
  • 直到整個父組件的拋出的promise對象都為resolve,將loading替換為真正的組件.

總結(jié)

Suspense其實就是將原來放在外面處理的異步請求也就是副作用放到渲染過程中進行操作,這樣render這個函數(shù)就不再是純函數(shù)了,但是非常直觀方便,不需要再用很多狀態(tài)來控制loading顯示,而異步請求的結(jié)果無法預(yù)測會導(dǎo)致很多bug.

等到Suspense支持數(shù)據(jù)請求的場景時,我會考慮把它運用到自己的項目中, 感覺確實方便很多本來就覺得Loading狀態(tài)有點多余,雖然現(xiàn)在用的是Dva,會自動給effect創(chuàng)建loading狀態(tài)的,還不是特別需要.

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • react子組件接收的props賦值給state的陷阱問題

    react子組件接收的props賦值給state的陷阱問題

    這篇文章主要介紹了react子組件接收的props賦值給state的陷阱問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 詳解react-router如何實現(xiàn)按需加載

    詳解react-router如何實現(xiàn)按需加載

    本篇文章主要介紹了react-router如何實現(xiàn)按需加載,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • React html中使用react的兩種方式

    React html中使用react的兩種方式

    這篇文章主要介紹了React html中使用react的兩種方式,本文給大家提到了React pwa的配置代碼,給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • react 項目中引入圖片的幾種方式

    react 項目中引入圖片的幾種方式

    本文主要介紹了react 項目中引入圖片,本文詳細的介紹了幾種方法,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • react+redux仿微信聊天界面

    react+redux仿微信聊天界面

    這篇文章主要介紹了react+redux仿微信聊天IM實例|react仿微信界面 ,本文圖文并茂給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-06-06
  • React Class組件生命周期及執(zhí)行順序

    React Class組件生命周期及執(zhí)行順序

    這篇文章主要介紹了React Class組件生命周期,包括react組件的兩種定義方式和class組件不同階段生命周期函數(shù)執(zhí)行順序,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2021-08-08
  • 關(guān)于getDerivedStateFromProps填坑記錄

    關(guān)于getDerivedStateFromProps填坑記錄

    這篇文章主要介紹了關(guān)于getDerivedStateFromProps填坑記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • React錯誤邊界Error Boundaries

    React錯誤邊界Error Boundaries

    錯誤邊界是一種React組件,這種組件可以捕獲發(fā)生在其子組件樹任何位置的JavaScript錯誤,并打印這些錯誤,同時展示降級UI,而并不會渲染那些發(fā)生崩潰的子組件樹
    2023-01-01
  • React?Hooks之useDeferredValue鉤子用法示例詳解

    React?Hooks之useDeferredValue鉤子用法示例詳解

    useDeferredValue鉤子的主要目的是在React的并發(fā)模式中提供更流暢的用戶體驗,特別是在有高優(yōu)先級和低優(yōu)先級更新的情況下,本文主要講解一些常見的使用場景及其示例
    2023-09-09
  • 詳解React Hooks是如何工作的

    詳解React Hooks是如何工作的

    React Hooks是在React 16.8版本新增的特性,在我看了React官網(wǎng)和一些博客對React Hook的講解后還是覺得沒有g(shù)et到本質(zhì)。本篇博客通過手動實現(xiàn)useState()來了解Hook的原理和本質(zhì)。閱讀此篇博客的前提是你要知道一些 React Hooks的基本用法和使用規(guī)則,不然會看得云里霧里。
    2021-05-05

最新評論

洮南市| 邻水| 桂东县| 高邑县| 英吉沙县| 渭源县| 西宁市| 都匀市| 平塘县| 泸西县| 偏关县| 郎溪县| 吉安市| 鄂州市| 年辖:市辖区| 淮滨县| 青神县| 东源县| 独山县| 商水县| 屏东县| 古浪县| 曲靖市| 闽侯县| 梧州市| 新安县| 满洲里市| 巴彦淖尔市| 岳阳县| 江西省| 石景山区| 临高县| 万全县| 青州市| 仁布县| 诏安县| 盐边县| 迁西县| 巴里| 泾源县| 淮安市|