<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>

          關(guān)于 React19,你需要了解的前因后果

          共 6021字,需瀏覽 13分鐘

           ·

          2024-04-11 23:34

          React當(dāng)前的穩(wěn)定版本是18.2,發(fā)布時(shí)間是22年6月,在此之后就沒有新的穩(wěn)定版本發(fā)布。

          直到今年2月15日,官方博客[1]才透露下一個(gè)穩(wěn)定版本的計(jì)劃。沒錯(cuò),他就是React19

          為什么時(shí)隔1年多才公布下個(gè)穩(wěn)定版本的計(jì)劃?

          為什么下個(gè)版本直接跳到了19?

          18我都還沒升呢,19就來了,是不是要學(xué)很多東西?

          這篇文章會(huì)為你詳細(xì)解答這些疑問。

          從React16聊起

          近年來React最為人津津樂道的版本應(yīng)該是16.8,這個(gè)版本引入了Hooks,為React(乃至整個(gè)前端框架領(lǐng)域)注入了新的活力。

          再之后的v17沒有新特性引入。既然沒有新特性引入,為什么要發(fā)布一個(gè)大版本(從16到17)呢?

          這是因?yàn)閺?strong style="color: rgb(145, 109, 213);background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 0px;">「同步更新」升級(jí)到「并發(fā)更新」React,中間存在breaking change

          這么大體量的框架,在升級(jí)時(shí)需要保證過程盡可能平順。這除了是一種專業(yè)、負(fù)責(zé)的體現(xiàn),更重要的,版本割裂會(huì)造成大量用戶損失(參考當(dāng)年ng1升級(jí)到anuglar2時(shí))。

          當(dāng)升級(jí)到18后,React團(tuán)隊(duì)發(fā)現(xiàn) —— 真正升級(jí)到18,并大量使用并發(fā)特性(比如useTransition)的開發(fā)者并不多。

          更常見的場(chǎng)景是 —— 知名開源庫集成并發(fā)特性,開發(fā)者再直接用這些庫。

          所以,React團(tuán)隊(duì)轉(zhuǎn)變策略,將迭代重心從「賦能開發(fā)者」轉(zhuǎn)變?yōu)?strong style="color: rgb(145, 109, 213);background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 0px;">「賦能開源庫」。那么,什么樣的庫受眾最多呢?顯然是框架。

          所以,React的重心逐漸變?yōu)?—— 賦能上層框架,開發(fā)者通過使用上層框架間接使用React

          為什么我說React團(tuán)隊(duì)轉(zhuǎn)變了策略,而不是React團(tuán)隊(duì)一開始的計(jì)劃就是「賦能上層框架」呢?

          如果一開始的計(jì)劃就是「賦能上層框架」React團(tuán)隊(duì)就不會(huì)花大量精力在「版本的漸進(jìn)升級(jí)上」 —— 反正開發(fā)者最終使用的會(huì)是上層框架(而不是React),版本割裂上層框架會(huì)解決,根本不需要引導(dǎo)開發(fā)者升級(jí)React

          策略改變?cè)斐傻挠绊?/span>

          策略轉(zhuǎn)變?cè)斐傻挠绊懯巧钸h(yuǎn)且廣泛的,這也是為什么18.2后一年多都沒有新的穩(wěn)定版本出現(xiàn)。

          最基本的影響是 —— 特性的迭代流程變了。

          React誕生的初衷是為了解決Meta內(nèi)部復(fù)雜的前端應(yīng)用,所以React之前的特性迭代流程是:

          1. 新特性開發(fā)完成

          2. 新特性在React內(nèi)部產(chǎn)品試用,并最終達(dá)到穩(wěn)定狀態(tài)

          3. 開源供廣大開發(fā)者使用

          但隨著策略轉(zhuǎn)變?yōu)?strong style="color: rgb(145, 109, 213);background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 0px;">「賦能上層框架」,勢(shì)必需要與主流上層框架團(tuán)隊(duì)(主要是Next.js)密切合作。

          如果按照原來的迭代流程,上層框架團(tuán)隊(duì)屬于Meta之外的第三方團(tuán)隊(duì),只能等新特性開源后才能使用,這種合作模式顯然太低效了。

          于是,React團(tuán)隊(duì)提出了一個(gè)新的特性發(fā)布渠道 —— canary,即:新特性開發(fā)完成后,可以先打一個(gè)canary版本的React供外部試用,等特性穩(wěn)定后再考慮將其加入穩(wěn)定版本中。

          可能有些存在于canary中的特性永遠(yuǎn)不會(huì)出現(xiàn)在穩(wěn)定版本的React中,但不妨礙一些開源庫鎖死canary版本的React,進(jìn)而使用這些特性。

          那么,為什么時(shí)隔1年多才公布下個(gè)穩(wěn)定版本的計(jì)劃?主要有4個(gè)原因。

          原因1:新特性主要服務(wù)于Next,沒必要出現(xiàn)在穩(wěn)定版本中

          策略改變除了影響「特性的迭代流程」,還讓React團(tuán)隊(duì)成員陷入一個(gè)兩難的境地 —— 我該優(yōu)先服務(wù)上層框架還是Meta

          我們可以發(fā)現(xiàn),在之前的迭代流程中,一切都圍繞Meta自身需求展開。React團(tuán)隊(duì)成員作為Meta員工,這個(gè)迭代流程再自然不過。

          但是,新的迭代流程需要密切與Next團(tuán)隊(duì)合作,那么問題來了 —— 作為Meta員工,新特性應(yīng)該優(yōu)先考慮Next的需求還是Meta的需求?

          為了完成「賦能上層框架」的任務(wù),顯然應(yīng)該更多考慮Next的需求。我們能看到一些React團(tuán)隊(duì)成員最終跳槽到Vercel,進(jìn)入Next團(tuán)隊(duì)。

          所以,在此期間產(chǎn)出的特性(比如server actionuseFormStatususeFormState)更多是服務(wù)于Next,而不是React

          如果基于這些特性發(fā)布新的穩(wěn)定版本,那不用Next的開發(fā)者用不到這些特性,用Next的開發(fā)者依賴的是canary React,所以此時(shí)升級(jí)穩(wěn)定版本是沒意義的。

          原因2:新特性必須滿足各種場(chǎng)景,交付難度大

          Nextweb框架,圍繞他創(chuàng)造的新React特性只用考慮web這一場(chǎng)景。

          React自身的定位是宿主環(huán)境無關(guān)的UI庫,還有大量開發(fā)者在非web的環(huán)境使用React(比如React Native),所以這些特性要出現(xiàn)在穩(wěn)定版本的React中,必須保證他能適配所有環(huán)境。

          舉個(gè)例子,Server Actions這一特性,用于「簡化客戶端與服務(wù)器數(shù)據(jù)發(fā)送的流程」,當(dāng)前主要應(yīng)用于NextApp Router模式中。

          比如下面代碼中的MyForm組件,當(dāng)表單提交后,serverAction函數(shù)的邏輯會(huì)在服務(wù)端執(zhí)行,這樣就能方便的進(jìn)行IO操作(比如操作數(shù)據(jù)庫):

          // 服務(wù)端代碼

          async function serverAction(event{
            'use server'
            // 在這里處理服務(wù)端邏輯,比如數(shù)據(jù)庫操作讀寫等
          }

          function MyForm({
            return (
              <form action={serverAction}>
                <input name="query" />
                <button type="submit">Search</button>
              </form>

            );
          }

          App Router的場(chǎng)景主要是RSC(React Server Component),除了RSC外,SSR場(chǎng)景下是不是也有表單?不使用服務(wù)端相關(guān)功能,單純使用React進(jìn)行客戶端渲染,是不是也有表單的場(chǎng)景?

          所以,Server Actions特性后來改名為Actions,因?yàn)椴恢?code style="font-size: 14px;line-height: 1.8em;letter-spacing: 0em;width: auto;height: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(145, 109, 213);font-weight: bolder;background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;">Server場(chǎng)景,其他場(chǎng)景也要支持Actions

          比如下面代碼中,在客戶端渲染的場(chǎng)景使用Actions特性:

          // 前端代碼

          const search = async (event) => {
            event.preventDefault();
            const formData = new FormData(event.target);
            const query = formData.get('query');

            // 使用 fetch 或其他方式發(fā)送數(shù)據(jù)
            const response = await fetch('/search'/*省略*/);

            // ...處理響應(yīng)
          };

          function MyForm({
            return (
              <form action={search}>
                <input name="query" />
                <button type="submit">Search</button>
              </form>

            );
          }

          你以為這就完了?還早。form組件支持Actions,那開發(fā)者自定義的組件能不能支持Actions這種「前、后端交互模式」

          比如下面的Calendar組件,之前通過onSelect事件響應(yīng)交互:

          <Calendar onSelect={eventHandler}>

          以后能不能用Actions的模式響應(yīng)交互:

          <Calendar selectAction={action}>

          如何將平平無奇的交互變成Actions交互呢?React團(tuán)隊(duì)給出的答案是 —— 用useTransition包裹。所以,這后面又涉及到useTransition功能的修改。

          Actions只是一個(gè)例子,可以發(fā)現(xiàn),雖然新特性是以web為始,但為了出現(xiàn)在穩(wěn)定版本中,需要以「覆蓋全場(chǎng)景」為終,自然提高了交付難度。

          原因3:老特性需要兼容的場(chǎng)景越來越多,工作量很大

          新特性越來越多,老特性為了兼容這些新特性也必須作出修改,這需要大量的時(shí)間開發(fā)、測(cè)試。

          舉兩個(gè)例子,Suspense在v16.6就引入了,它「允許組件“等待”某些內(nèi)容變得可用,并在此期間顯示一個(gè)加載指示器(或其他后備內(nèi)容)」

          Suspense最初只支持懶加載組件(React.lazy)這一場(chǎng)景。隨著React新特性不斷涌現(xiàn),Suspense又相繼兼容了如下場(chǎng)景:

          • Actions提交后的等待場(chǎng)景

          • 并發(fā)更新的等待場(chǎng)景

          • Selective Hydration的加載場(chǎng)景

          • RSC流式傳輸?shù)牡却龍?chǎng)景

          • 任何data fetching場(chǎng)景

          為了兼容這些場(chǎng)景,Suspense的代碼量已經(jīng)非常恐怖了,但開發(fā)者對(duì)此是無感知的。

          再舉個(gè)和SuspenseuseEffect這兩個(gè)特性相關(guān)的例子。

          Suspense為什么能在「中間狀態(tài)」「完成狀態(tài)」之間切換?是因?yàn)樵?code style="font-size: 14px;line-height: 1.8em;letter-spacing: 0em;width: auto;height: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(145, 109, 213);font-weight: bolder;background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;">Suspense的源碼中,他的內(nèi)部存在一個(gè)Offscreen組件,用于完成兩顆子Fiber樹的切換。

          React團(tuán)隊(duì)希望將Offscreen組件抽離成一個(gè)單獨(dú)的新特性(新名字叫Activity組件),起到類似VueKeep-Alive組件的作用。

          Activity組件既然能讓組件顯/隱,那勢(shì)必會(huì)影響組件的useEffect的觸發(fā)時(shí)機(jī)。畢竟,如果一個(gè)組件隱藏了,但他的useEffect create函數(shù)觸發(fā)了,會(huì)是一件很奇怪的事情。

          所以,為了落地Activity組件,useEffect的觸發(fā)邏輯又會(huì)變得更復(fù)雜。

          原因4:特性必須形成體系才能交付

          雖然這一年React團(tuán)隊(duì)開發(fā)了很多特性,但很多特性無法單獨(dú)交付,必須構(gòu)成一個(gè)體系后再統(tǒng)一交付。

          比如剛才提到的useFormStatususeFormState是服務(wù)于Actions特性的,Actions又是由Server Actions演化而來的,Server Actions又是RSC(React服務(wù)端組件)體系下的特性。

          單獨(dú)將useFormStatus發(fā)布在穩(wěn)定版本中是沒意義的,他屬于RSC體系下的一環(huán)。

          所以,即使新特性已經(jīng)準(zhǔn)備就緒,他所在的體系還沒準(zhǔn)備好的話,那體系下的所有特性都不能在穩(wěn)定版本中交付。

          總結(jié)

          為什么時(shí)隔1年多才公布下個(gè)穩(wěn)定版本的計(jì)劃?主要是4個(gè)原因:

          1. 新特性主要服務(wù)于Next,沒必要出現(xiàn)在穩(wěn)定版本中

          2. 新特性必須滿足各種場(chǎng)景,交付難度大

          3. 老特性需要兼容的場(chǎng)景越來越多,工作量很大

          4. 特性必須形成體系才能交付

          那為什么下個(gè)穩(wěn)定版本不是v18.x而是v19呢?這是因?yàn)椴糠中绿匦裕ㄖ饕?code style="font-size: 14px;line-height: 1.8em;letter-spacing: 0em;width: auto;height: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(145, 109, 213);font-weight: bolder;background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;">Asset Loading、Document Metadata這兩類特性)對(duì)于一些應(yīng)用會(huì)產(chǎn)生breaking change,所以需要發(fā)一個(gè)大版本。

          從上述4個(gè)原因中的第四點(diǎn)可以知道,既然有v19的消息,勢(shì)必是因?yàn)?strong style="color: rgb(145, 109, 213);background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 0px;">「已經(jīng)有成體系的新特性可以交付」,那是不是意味著要學(xué)很多東西呢?

          這一點(diǎn)倒不用擔(dān)心,如果你不用Next,那你大概率不會(huì)接觸到RSC,既然不會(huì)接觸RSC,那么RSC體系下的新特性你都不會(huì)用到。

          v19對(duì)你最大的影響可能就是新特性對(duì)老API的影響了,比如:

          • useContext變?yōu)?code style="height: auto;font-size: 14px;line-height: 1.8em;letter-spacing: 0em;width: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(145, 109, 213);font-weight: bolder;background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;">use(promise)

          • Activity組件使useEffect的觸發(fā)時(shí)機(jī)更復(fù)雜(應(yīng)該不會(huì)在v19的第一個(gè)版本中)

          這些的學(xué)習(xí)成本都不大。

          關(guān)于v19的進(jìn)一步消息,會(huì)在今年5月15~16的React Conf[2]公布。

          參考資料
          [1]

          官方博客: https://react.dev/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024

          [2]

          React Conf: https://conf.react.dev/





          瀏覽 52
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  大吊操色逼 | 无码豆花视频 | 国产精品福利在线播放 | 天天草天天射天天撸 | 91日韩|