自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

第一個可以在條件語句中使用的原生Hook誕生了

開發(fā) 前端
Use作為「讀取異步數(shù)據(jù)的原語」,可以配合Suspense實現(xiàn)「數(shù)據(jù)請求、加載、返回」的邏輯。

大家好,我卡頌。

在10月13日的first-class-support-for-promises RFC[1]中,介紹了一種新的hook? —— use。

use?什么?就是use?,這個hook?就叫use。這也是第一個:

  • 可以在條件語句中書寫的hook
  • 可以在其他hook回調(diào)中書寫的hook

本文來聊聊這個特殊的hook。

use是什么

我們知道,async函數(shù)會配合await關(guān)鍵詞使用,比如:

async function load() {
const {name} = await fetchName();
return name;
}

類似的,在React組件中,可以配合use起到類似的效果,比如:

function Cpn() {
const {name} = use(fetchName());
return <p>{name}</p>;
}

可以認為,use的作用類似于:

  • async await?中的await。
  • generator?中的yield。

use?作為「讀取異步數(shù)據(jù)的原語」,可以配合Suspense實現(xiàn)「數(shù)據(jù)請求、加載、返回」的邏輯。

舉個例子,下述例子中,當fetchNote?執(zhí)行異步請求時,會由包裹Note?的Suspense組件渲染「加載中狀態(tài)」。

當請求成功時,會重新渲染,此時note數(shù)據(jù)會正常返回。

當請求失敗時,會由包裹Note的ErrorBoundary組件處理失敗邏輯。

function Note({id}) {
const note = use(fetchNote(id));
return (
<div>
<h1>{note.title}</h1>
<section>{note.body}</section>
</div>
);
}

其背后的實現(xiàn)原理并不復雜:

  1. 當Note組件首次render,fetchNote發(fā)起請求,會throw promise,打斷render流程。
  2. 以Suspense fallback作為渲染結(jié)果。
  3. 當promise狀態(tài)變化后重新觸發(fā)渲染。
  4. 根據(jù)note的返回值渲染。

實際上這套「基于promise的打斷、重新渲染流程」當前已經(jīng)存在了。use的存在就是為了替換上述流程。

與當前React?中已經(jīng)存在的上述「promise流程」不同,use?僅僅是個「原語」(primitives),并不是完整的處理流程。

比如,use并沒有「緩存promise」的能力。

舉個例子,在下面代碼中fetchTodo?執(zhí)行后會返回一個promise,use?會消費這個promise。

async function fetchTodo(id) {
const data = await fetchDataFromCache(`/api/todos/${id}`);
return {contents: data.contents};
}
function Todo({id, isSelected}) {
const todo = use(fetchTodo(id));
return (
<div className={isSelected ? 'selected-todo' : 'normal-todo'}>
{todo.contents}
</div>
);
}

當Todo組件的id prop變化后,觸發(fā)fetchTodo重新請求是符合邏輯的。

但是當isSelected prop變化后,Todo組件也會重新render,fetchTodo執(zhí)行后會返回一個新的promise。

返回新的promise不一定產(chǎn)生新的請求(取決于fetchTodo的實現(xiàn)),但一定會影響React接下來的運行流程(比如不能命中性能優(yōu)化)。

這時候,需要配合React提供的cache API(同樣處于RFC)。

下述代碼中,如果id prop不變,fetchTodo始終返回同一個promise:

const fetchTodo = cache(async (id) => {
const data = await fetchDataFromCache(`/api/todos/${id}`);
return {contents: data.contents};
});

use的潛在作用

當前,use的應用場景局限在「包裹promise」。

但是未來,use會作為客戶端中處理異步數(shù)據(jù)的主要手段,比如:

  • 處理context

use(Context)?能達到與useContext(Context)?一樣的效果,區(qū)別在于前者可以在條件語句,以及其他hook回調(diào)內(nèi)執(zhí)行。

  • 處理state

可以利用use實現(xiàn)新的原生狀態(tài)管理方案:

const currentState = use(store);
const latestValue = use(observable);

為什么不使用async await

本文開篇提到,use原語類似async await中的await,那為什么不直接使用async await呢?類似下面這樣:

// Note 是 React 組件
async function Note({id, isEditing}) {
const note = await db.posts.get(id);
return (
<div>
<h1>{note.title}</h1>
<section>{note.body}</section>
{isEditing ? <NoteEditor note={note} /> : null}
</div>
);
}

有兩方面原因。

一方面,async await的工作方式與React客戶端處理異步時的邏輯不太一樣。

當await的請求resolve后,調(diào)用棧是從await語句繼續(xù)執(zhí)行的(generator中yield也是這樣)。

而在React中,更新流程是從根組件開始的,所以當數(shù)據(jù)返回后,更新流程是從根組件從頭開始的。

改用async await的方式勢必對當前React底層架構(gòu)帶來挑戰(zhàn)。最起碼,會對性能優(yōu)化產(chǎn)生不小的影響。

另一方面,async await這種方式接下來會在Server Component中實現(xiàn),也就是異步的服務(wù)端組件。

服務(wù)端組件與客戶端組件都是React組件,但前者在服務(wù)端渲染(SSR),后者在客戶端渲染(CSR),如果都用async await,不太容易從代碼層面區(qū)分兩者。

總結(jié)

use?是一個「讀取異步數(shù)據(jù)的原語」,他的出現(xiàn)是為了規(guī)范React在客戶端處理異步數(shù)據(jù)的方式。

既然是原語,那么他的功能就很底層,比如不包括請求的緩存功能(由cache處理)。

之所以這么設(shè)計,是因為React?團隊并不希望開發(fā)者直接使用他們。這些原語的受眾是React生態(tài)中的其他庫。

比如,類似SWR?、React-Query?這樣的請求庫,就可以結(jié)合use?,再結(jié)合自己實現(xiàn)的請求緩存策略(而不是使用React?提供的cache方法)

各種狀態(tài)管理庫,也可以將use作為其底層狀態(tài)單元的容器。

值得吐槽的是,Hooks?文檔中hook的限制那一節(jié)恐怕得重寫了。

參考資料

[1]first-class-support-for-promises RFC:https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md。

責任編輯:姜華 來源: 魔術(shù)師卡頌
相關(guān)推薦

2015-04-15 11:28:04

Apple Watch殺手應用

2009-06-26 16:07:43

MyEclipse開發(fā)Hibernate程序

2014-05-26 15:25:43

網(wǎng)絡(luò)維護華為

2024-07-03 08:24:58

2013-10-30 22:10:28

Clouda程序

2022-10-17 10:28:05

Web 組件代碼

2023-06-01 08:24:08

OpenAIChatGPTPython

2022-11-01 07:23:55

Dockernetcore程序

2020-11-13 07:08:51

Spring Boot應用Spring

2011-03-03 21:04:08

bug程序員

2011-03-21 14:24:13

Debian 6

2013-01-14 09:44:58

JavaScriptJSJS框架

2010-07-30 14:58:06

Flex應用

2012-02-08 11:15:38

HibernateJava

2021-04-07 13:38:27

Django項目視圖

2023-09-21 22:43:17

Django框架

2011-08-29 15:12:24

UbuntuLinux模塊

2021-12-13 11:31:36

排序數(shù)組數(shù)據(jù)結(jié)構(gòu)算法

2020-02-05 15:23:00

語言編程文言文

2021-11-02 14:54:41

排序數(shù)組元素
點贊
收藏

51CTO技術(shù)棧公眾號