<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          react18 來了,我 get 到...

          共 5838字,需瀏覽 12分鐘

           ·

          2021-12-25 04:36

          點擊上方藍色字體,選擇“標星公眾號”

          優(yōu)質文章,第一時間送達


          -? ?1. automatic batching:自動批處理。? ? -

          batching 批處理,說的是,可以將回調函數(shù)中多個 setState 事件合并為一次渲染,因此是異步的。

          解決的問題是多次同值、不同值 setState, 期望最后顯示的是最后一次 setState 的結果,減少渲染。

          ??const?Index?=?()?=>?{
          ????const?[name,?setName]?=?useState('')
          ????const?[age,?setAge]?=?useState(0)
          ????
          ????const?change?=?()?=>?{
          ??????setName('a')
          ??????setAge(1)?
          ??????//?僅觸發(fā)一次渲染,批處理,2次setState合并為一次渲染

          ??????//?需需要立即重渲染,需要手動調用
          ??????//?ReactDOM.flushSync(()?=>?{
          ??????//???setName('a')?//?立即執(zhí)行渲染
          ??????//???setAge(1)?//?立即執(zhí)行渲染
          ??????//???//?不會合并處理,即沒有批處理,觸發(fā)2次
          ??????//?});
          ????}

          ????console.log(1)?//?只打印一次

          ????return?(
          ??????

          ????????

          name:?{name}


          ????????

          age:?{age}


          ????????更改
          ??????

          ????)
          ??}

          但是 react 18 之前,在 promise、timeout 或者 event 回調中調用多次 setState,由于丟失了上下文,無法做合并處理,所以每次 setState 調用都會立即觸發(fā)一次重渲染:

          ?const?Index?=?()?=>?{
          ???const?[name,?setName]?=?useState('')
          ???const?[age,?setAge]?=?useState(0)
          ???
          ???const?change?=?()?=>?{
          ?????setTimeout(()?=>?{
          ???????setName('a')?//?立即執(zhí)行渲染
          ???????setAge(1)?//?立即執(zhí)行渲染
          ???????//?不會合并處理,即沒有批處理,觸發(fā)2次

          ???????//?若需要批處理,需要手動調用
          ???????//?ReactDom.unstable_batchedUpdates(()?=>?{
          ???????//???setName('a')
          ???????//???setAge(1)?
          ???????//???//?合并處理
          ???????//?})
          ???????//?并且將?ReactDOM.render?替換為?ReactDOM.createRoot?調用方式
          ???????//?舊?ReactDOM.render("home"?/>,?container);
          ???????//?新?ReactDOM.createRoot(container).render("home"?/>)
          ?????},?0);
          ???}

          ???console.log(1)?//?打印2次

          ???return?(
          ?????

          ???????

          name:?{name}


          ???????

          age:?{age}


          ???????更改
          ?????

          ???)
          ?}

          react18,在 promise、timeout 或者 event 回調中調用多次 setState,會合并為一次渲染。提升渲染性能。

          v18實現(xiàn)「自動批處理」的關鍵在于兩點:

          • 增加調度的流程

          • 不以全局變量 executionContext 為批處理依據(jù),而是以更新的「優(yōu)先級」為依據(jù)




          -? ?2. concurrent apis:全新的并發(fā) api比如:startTransition? ? -

          Concurrent:并發(fā),采用可中斷的遍歷方式更新 Fiber Reconciler。是漸進升級策略的產(chǎn)物。

          不同更新觸發(fā)的視圖變化是有輕重緩急的,讓高優(yōu)更新對應的視圖變化先渲染,那么就能在設備性能不變的情況下,讓用戶更快看到他們想看到的UI。

          案例:用戶操作滑塊,然后響應樹的變化?;瑝K響應是高優(yōu)先級的,而樹的變化可以認為是低優(yōu)先級的。

          demo

          未開啟:可以看到滑塊的拖動有卡頓

          開啟:可以看到滑塊的拖動,非常的絲滑順暢

          代碼實現(xiàn),將設置更新樹的 setState,放到 startTransition 中。而更新滑塊的不變,認為是高優(yōu)先級,優(yōu)先響應。

          2部分:

          • 緊急響應:滑塊。

          • 過渡更新:根據(jù)滑塊,呈現(xiàn)結果內容。

          ?import?{?useTransition?}?from?'react';
          ??const?[isPending,?startTransition]?=?useTransition();

          ??//?更改滑塊觸發(fā)
          ??function?changeTreeLean(event)?{
          ??????const?value?=?Number(event.target.value);
          ??????setTreeLeanInput(value);?//?更新滑塊

          ??????//?是否開啟startTransition
          ??????if?(enableStartTransition)?{
          ????????startTransition(()?=>?{
          ????????? setTreeLean(value);?//?這個變慢,根據(jù)滑塊,呈現(xiàn)結果內容。
          ????????});

          ????????// react18之前,想要有類似功能。變體,setTimeout,防抖節(jié)流
          ????????//?setTimeout(()?=>?{
          ????????//???setTreeLean(value)
          ????????//?},?0)

          ??????}?else?{
          ????????setTreeLean(value);
          ??????}
          ??}

          ??//?過渡期間可以這么處理
          ??{isPending????:?}

          比 setTimeout 更好,能有狀態(tài) isPending,且更早更快的呈現(xiàn)更新到界面上(微任務里處理)。而且 setTimeout 是不可中斷的,而 startTransition 是可中斷的,不會影響頁面交互響應。

          依賴于React底層實現(xiàn)的優(yōu)先級調度模型,被 startTransition 包含的 setState 的優(yōu)先級會被設置為低優(yōu)先級的過渡更新。




          -? ?3. suspense:更好的 suspense。更好的支持在 ssr 和 異步數(shù)據(jù) 場景下使用 suspense。? ? -


          1. ssr 下支持,可參考:React18 中的新 Suspense SSR 架構

          2.透明的異步數(shù)據(jù)處理(未來18.x支持)

          和寫同步邏輯代碼一樣,寫異步代碼邏輯。大大的簡化了代碼邏輯的書寫。把代數(shù)效應應用到極致了,把異步的副作用剝離了。

          代數(shù)效應是函數(shù)式編程中的一個概念,用于將副作用從函數(shù)調用中分離。

          場景案例:demo,顯示暢銷書排行榜。

          其中,名稱和日期是一個接口獲取,而下面的列表是另一個接口獲取。

          從圖中,可以明顯感到 with suspense 的效果更絲滑,用戶體驗更好。而代碼也非常簡潔。部分代碼如下:

          //?接口部分
          import?{?fetch?}?from?"react-fetch"

          export?function?fetchBookLists()?{
          ??const?res?=?fetch(`
          ??https://api.nytimes.com/svc/books/v3/lists/names.json?api-key=${API_KEY}`)

          ??const?json?=?res.json()

          ??if?(json.status?===?"OK")?{
          ????return?json.results
          ??}?else?{
          ????console.log(json)
          ????throw?new?Error("Loading?failed,?likely?rate?limit")
          ??}
          }

          //?組件部分
          //?沒有處理?loading?狀態(tài)等的異步處理,和同步已經(jīng)完全一致的代碼書寫
          const?Content?=?()?=>?{
          ??const?list?=?fetchBookLists()[0]

          ??return?(
          ????<>
          ??????

          From?{list.display_name}


          ??????
          ????????Published?on?{list.newest_published_date}
          ??????
          ??????
          ????
          ??)
          }

          export?const?BestSellers?=?()?=>?{
          ??return?(
          ????}>
          ??????{/*?loading?must?happen?inside?a??*/}
          ??????
          ????

          ??)
          }

          而在 react18 之前,你得這么寫:

          //?接口部分
          import?{?fetch?}?from?"react-fetch"
          export?async?function?fetchBookLists()?{
          ??const?res?=?await?fetch(`
          ??https://api.nytimes.com/svc/books/v3/lists/names.json?api-key=${API_KEY}`)

          ??const?json?=?await?res.json()

          ??if?(json.status?===?"OK")?{
          ????return?json.results
          ??}?else?{
          ????console.log(json)
          ????throw?new?Error("Loading?failed,?likely?rate?limit")
          ??}
          }

          //?組件部分,按照異步的邏輯寫,寫loading,對異步結果的處理等
          function?useNYTBestSellerLists()?{
          ??//?poor?man's?useQuery?implementation
          ??const?[isLoading,?setIsLoading]?=?useState(false)
          ??const?[lists,?setLists]?=?useState(null)

          ??useEffect(()?=>?{
          ????setIsLoading(true)

          ????fetchBookLists()
          ??????.then((lists)?=>?{
          ????????setLists(lists)
          ????????setIsLoading(false)
          ??????})
          ??????.catch(()?=>?setIsLoading(false))
          ??},?[])

          ??return?{?isLoading,?lists?}
          }

          export?const?BestSellers?=?()?=>?{
          ??const?{?isLoading,?lists?}?=?useNYTBestSellerLists();

          ??if?(isLoading)?{
          ????return?;
          ??}

          ??if?(!lists)?{
          ????return?"not?loading?or?error";
          ??}

          ??const?list?=?lists[0];

          ??return?(
          ????<>
          ??????

          From?{list.display_name}


          ??????
          ????????Published?on?{list.newest_published_date}
          ??????
          ??????
          ????
          ??);
          }

          3.優(yōu)化 suspense 的行為表現(xiàn)。

          場景舉例:

          ????loading...}>
          ???????//?為?React.lazy?包裹的異步加載組件
          ???????//?普通組件
          ????

          由于 Suspense 會等待子孫組件中的異步請求完畢后再渲染,所以當代碼運行時頁面首先會渲染 fallback:loading。而在loading這個過程中,頁面表現(xiàn)是一致的,但是背后的行為是不一致的:

          • react18 之前:即在 Legacy Suspense 中,Sibling 組件會立即安裝到 DOM 并觸發(fā)其效果/生命周期。頁面上隱藏。

          • react18:即在 Concurrent Suspense 中,Sibling 組件沒有掛載到 DOM。它的效果/生命周期也不會在 ComponentThatSuspends 解決之前觸發(fā)。

          react18,Sibling 不會執(zhí)行,會等 suspense 包裹的組件都加載完才執(zhí)行渲染

          優(yōu)化的是提交渲染的流程:

          打斷兄弟組件并阻止他們提交。等待提交 Suspense 邊界內的所有內容- 掛起的組件及其所有兄弟組件 - 直到掛起的數(shù)據(jù)解決。然后在一個單一的、一致的批次中同時提交整個樹渲染。




          -? ?4. 其他? ? -

          比如:新 Hook —— useId

          解決問題:ssr 場景下,客戶端、服務端生成的id不匹配!官方推出 Hook——useId解決,每個 id 代表該組件在組件樹中的層級結構。

          function?Checkbox()?{
          ??//?生成唯一、穩(wěn)定id
          ??const?id?=?useId();
          ??return?(
          ????<>
          ??????Do?you?like?React?
          ??????type="checkbox"?name="react"?id={id}?/>
          ????
          ??);
          );



          -? ?最后? ? -


          這幾個重大的更新,目的都是較少渲染、根據(jù)優(yōu)先級響應、提升性能、擁有更好的體驗。非常值得期待。

          想嘗鮮的可安裝 react18 beta 版(2021-11-16發(fā)布的)

          #?npm
          npm?install?react@beta?react-dom@beta
          #?yarn
          yarn?add?react@beta?react-dom@beta

          ? 作者?|??ESnail

          來源 |??cnblogs.com/EnSnail/p/15679835.html


          瀏覽 65
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产综合自拍视频 | 成人视频在线免费 | 中国女人性交毛片 | 国产三级片在线观看视频成人电影 | 手机在线看成人片 |