日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

React Suspense 進(jìn)階用法,結(jié)合 useTransition 使用

來源: 責(zé)編: 時間:2024-06-14 17:40:37 167觀看
導(dǎo)讀一、更舒適的交互先來看一下我們想要實現(xiàn)的交互效果,如圖所示。我們在前面學(xué)習(xí)了 Suspense。Suspense 的 fallback 與子組件內(nèi)容的顯示是一個互斥關(guān)系。因此,當(dāng)我們在請求過程中,需要顯示 Loading 時,內(nèi)容就會被隱藏掉。<

uQJ28資訊網(wǎng)——每日最新資訊28at.com

一、更舒適的交互

先來看一下我們想要實現(xiàn)的交互效果,如圖所示。uQJ28資訊網(wǎng)——每日最新資訊28at.com

uQJ28資訊網(wǎng)——每日最新資訊28at.com

我們在前面學(xué)習(xí)了 Suspense。Suspense 的 fallback 與子組件內(nèi)容的顯示是一個互斥關(guān)系。因此,當(dāng)我們在請求過程中,需要顯示 Loading 時,內(nèi)容就會被隱藏掉。uQJ28資訊網(wǎng)——每日最新資訊28at.com

<Suspense fallback={<Loading />}>  <Albums /></Suspense>

之前我們實現(xiàn)的交互效果如下。uQJ28資訊網(wǎng)——每日最新資訊28at.com

uQJ28資訊網(wǎng)——每日最新資訊28at.com

這種交互效果其實還可以,但是許多對交互有更高要求的團(tuán)隊,不會接受這樣的頁面大幅度抖動的交互。uQJ28資訊網(wǎng)——每日最新資訊28at.com

例如在 antd 的 Table 組件中,它們選擇的方案是在列表組件上覆蓋了一個 Loading,此時的 Loading 效果與列表并非是一個互斥關(guān)系。這樣的交互體驗要比用 Loading 整體替換掉表格要好很多。uQJ28資訊網(wǎng)——每日最新資訊28at.com

uQJ28資訊網(wǎng)——每日最新資訊28at.com

所以,在目前學(xué)習(xí)階段,我們面臨的一個困惑就是,在使用 Suspense + use 來完成功能的同時,又如何優(yōu)雅的做到這種非互斥的交互效果呢?uQJ28資訊網(wǎng)——每日最新資訊28at.com

我們想要的最佳交互效果氛圍兩個階段。uQJ28資訊網(wǎng)——每日最新資訊28at.com

  •  初始化階段,渲染 Suspense fallback 對應(yīng)的組件。此時內(nèi)部還沒有辦法顯示,我們可以放置一個 Loading 或者骨架屏組件。
  • 更新階段,我們希望阻止 fallback 的出現(xiàn)。直接在 Suspense 子組件內(nèi)部處理更新階段的 loading。這樣就可以確保更新階段,子組件內(nèi)容與更新 loading 共存。

但是以目前學(xué)習(xí)到的知識點,肯定還做不到這樣的效果,因此我們要引入新的概念:useTransition。uQJ28資訊網(wǎng)——每日最新資訊28at.com

二、useTransition 概念解讀

useTransition 是 React 專門為并發(fā)模式提供的一個基礎(chǔ) hook,它能夠幫助我們在不阻塞 UI 渲染的情況下更新狀態(tài)。意思就是說,我們可以借助 useTransition 將任務(wù)的優(yōu)先級調(diào)得比 I/O 的響應(yīng)低一些。uQJ28資訊網(wǎng)——每日最新資訊28at.com

const [isPending, startTransition] = useTransition()

useTransition 的調(diào)用不需要參數(shù),他的執(zhí)行返回兩個參數(shù)。uQJ28資訊網(wǎng)——每日最新資訊28at.com

isPending:是否還存在等待處理的 transition,表示被降低優(yōu)先級的更新任務(wù)還沒有處理完成。uQJ28資訊網(wǎng)——每日最新資訊28at.com

startTransition:標(biāo)記任務(wù)的優(yōu)先級為 transition,該優(yōu)先級低于正常任務(wù)更新。它的用法如下,我們會將更新任務(wù)在它的回調(diào)函數(shù)中執(zhí)行。uQJ28資訊網(wǎng)——每日最新資訊28at.com

function TabContainer() {  const [isPending, startTransition] = useTransition();  const [tab, setTab] = useState('about');  function selectTab(nextTab) {    startTransition(() => {      setTab(nextTab);    });  }  // ……}

在優(yōu)先級的排序中,被 startTransition 標(biāo)記的任務(wù)比 Suspense fallback 更高一些。因此,我們可以利用這個特性,來避免 fallback 的渲染,當(dāng) startTransition 標(biāo)記的任務(wù)執(zhí)行完成,請求已經(jīng)完成,此時 fallback 也就得不到渲染的機(jī)會了。uQJ28資訊網(wǎng)——每日最新資訊28at.com

這里需要注意的是,標(biāo)記的任務(wù)指的不是 setState ,而是對應(yīng)的 UI 渲染任務(wù),傳遞給 startTransition 的回調(diào)函數(shù)必須是同步函數(shù)。uQJ28資訊網(wǎng)——每日最新資訊28at.com

我們可以正常這樣使用。uQJ28資訊網(wǎng)——每日最新資訊28at.com

startTransition(() => {  // ? 在調(diào)用 startTransition 中更新狀態(tài)  setPage('/about');});

但是不能在回調(diào)函數(shù)中使用異步調(diào)用。這樣會導(dǎo)致并發(fā)模式的任務(wù)排序出現(xiàn)問題。uQJ28資訊網(wǎng)——每日最新資訊28at.com

startTransition(() => {  // ? 在調(diào)用 startTransition 后更新狀態(tài)  setTimeout(() => {    setPage('/about');  }, 1000);});

但是,我們可以把 startTransition 傳遞給 setTimeout。uQJ28資訊網(wǎng)——每日最新資訊28at.com

setTimeout(() => {  startTransition(() => {    // ? 在調(diào)用 startTransition 中更新狀態(tài)    setPage('/about');  });}, 1000);
startTransition(async () => {  await someAsyncFunction();  // ? 在調(diào)用 startTransition 后更新狀態(tài)  setPage('/about');});
await someAsyncFunction();startTransition(() => {  // ? 在調(diào)用 startTransition 中更新狀態(tài)  setPage('/about');});

三、Suspense + useTransition

現(xiàn)在基于前面的知識點,我們來著手解決我們自己案例中的交互體驗的提升。先來回顧一下之前的代碼。uQJ28資訊網(wǎng)——每日最新資訊28at.com

export default function Index() {  const [api, setApi] = useState(getApi)  function __clickToGetMessage() {    setApi(getApi())  }    return (    <div>      <div id='tips'>點擊按鈕獲取一條新的數(shù)據(jù)</div>      <button onClick={__clickToGetMessage} disabled={isPending}>獲取數(shù)據(jù)</button>      <div className="content">        <Suspense fallback={<div>loading...</div>}>          <Item api={api} isPending={isPending} />        </Suspense>      </div>    </div>  )}

在這個基礎(chǔ)之上,我們只需要引入 useTransition 的使用即可。uQJ28資訊網(wǎng)——每日最新資訊28at.com

export default function Index() {  const [api, setApi] = useState(getApi)  const [isPending, startTransition] = useTransition()  function __clickToGetMessage() {    startTransition(() => {      setApi(getApi())    })  }    ...}

setApi 所引發(fā)的任務(wù)更新被標(biāo)記為 transition,他的優(yōu)先級比 fallback 更高,因此此時我們需要等待 setApi 執(zhí)行完成。isPending 表示是否還有待處理的 transition 任務(wù),在這個案例中,他可以表示請求正在發(fā)生,作用與 loading 完全一致。uQJ28資訊網(wǎng)——每日最新資訊28at.com

因此,我們可以將 isPending 傳遞給子組件,在子組件內(nèi)部通過 isPending 來設(shè)計 loading UI。我們這里將組件的透明度調(diào)低。uQJ28資訊網(wǎng)——每日最新資訊28at.com

<Item api={api} isPending={isPending} />
const Item = (props) => {  const {isPending, api} = props  const joke = use(api)  return (    <div       className='a_value'       style={{opacity: isPending ? 0.5 : 1}}    >{joke.value}</div>  )}

最終的演示效果如下:uQJ28資訊網(wǎng)——每日最新資訊28at.com

uQJ28資訊網(wǎng)——每日最新資訊28at.com

loading... 字樣的出現(xiàn)表示初始化時請求接口。整體變淺表示更新時請求接口。完整的達(dá)到了我們的訴求。uQJ28資訊網(wǎng)——每日最新資訊28at.com

四、input 中的實時請求

我們可以利用同樣的方式,在搜索快速輸入時做到這個交互。每一個字符的變化,在之前的嘗試中,我們都會請求一次接口。因此之前的交互如下:uQJ28資訊網(wǎng)——每日最新資訊28at.com

uQJ28資訊網(wǎng)——每日最新資訊28at.com

我們希望如果列表已經(jīng)顯示過一次,那么在搜索過程中,列表就顯示舊值,而不用切換到 fallback 的 Loading 組件。uQJ28資訊網(wǎng)——每日最新資訊28at.com

uQJ28資訊網(wǎng)——每日最新資訊28at.com

代碼的調(diào)整與上面的案例幾乎一樣,如下:uQJ28資訊網(wǎng)——每日最新資訊28at.com

export default function Index() {  const [api, setApi] = useState(postApi)  const [isPending, startTransition] = useTransition()  function __inputChange() {    startTransition(() => {      api.cancel()      setApi(postApi())    })  }  ....

但是,我們注意觀察交互動畫,當(dāng)我們輸入完之后,過了很長一段時間,isPending 狀態(tài)才發(fā)生變化。也就是說,在這很長的時間里,一直有 transition 任務(wù)在執(zhí)行。為什么會發(fā)生這種事情呢?然后我們觀察了一下 network 面板,發(fā)現(xiàn)每一個請求都發(fā)生了。取消請求的代碼并沒有生效。uQJ28資訊網(wǎng)——每日最新資訊28at.com

uQJ28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)然,在官方文檔中,也提到了,如果我們期望在交互過程中減少冗余請求的發(fā)生,我們可以繼續(xù)使用防抖/節(jié)流來解決問題。uQJ28資訊網(wǎng)——每日最新資訊28at.com

uQJ28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-93868-0.htmlReact Suspense 進(jìn)階用法,結(jié)合 useTransition 使用

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 為什么要推薦使用現(xiàn)代化PHP框架?

下一篇: 抖音集團(tuán)成 2024 年巴黎奧運(yùn)會持權(quán)轉(zhuǎn)播商

標(biāo)簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 绥阳县| 正镶白旗| 黑河市| 定远县| 托克逊县| 格尔木市| 盐城市| 余江县| 宁德市| 新余市| 深州市| 广河县| 巴东县| 晋城| 洛隆县| 聂拉木县| 漯河市| 承德县| 盐边县| 宜川县| 社会| 天长市| 遂溪县| 东安县| 常熟市| 岱山县| 阳泉市| 莒南县| 广河县| 澄迈县| 唐海县| 宿州市| 探索| 涟水县| 岳阳市| 和田县| 沙河市| 平陆县| 清苑县| 开阳县| 佳木斯市|