開(kāi)發(fā)者對(duì) React 19 Beta 發(fā)布感到困惑
React 19 beta 終于來(lái)了,但其中一些非常棒的功能卻因困惑和溝通不暢而黯然失色。
React 19 beta 可以隨時(shí)發(fā)布,但現(xiàn)在選擇在 2024 年 3 月 25 日發(fā)布實(shí)屬最佳,因?yàn)殚_(kāi)發(fā)世界暫時(shí)沒(méi)有其他重大事件。
編譯器尚未到來(lái)
一些開(kāi)發(fā)者對(duì)這次發(fā)布持樂(lè)觀態(tài)度,但也有許多人擔(dān)心此次版本中沒(méi)有提到編譯器。
React 編譯器是 React 團(tuán)隊(duì)長(zhǎng)時(shí)間實(shí)驗(yàn)的工具,目前用于運(yùn)行 Instagram,并且預(yù)計(jì)很快會(huì)發(fā)布。開(kāi)發(fā)者們對(duì)編譯器的期望很高,因?yàn)樗鼘p少手動(dòng)記憶化的需求,這是一項(xiàng)耗時(shí)且容易出錯(cuò)的 React 修補(bǔ)工作。有了編譯器,React 將更善于判斷何時(shí)需要更新 UI,何時(shí)不需要,從而提升性能。
但我們?nèi)圆淮_定編譯器何時(shí)能正式發(fā)布??赡茉谖逶拢苍S是 2024 年或 2026 年?希望它能在新 GTA 發(fā)布前上線!
你將享受更多的服務(wù)器端支持
SPA(單頁(yè)應(yīng)用)愛(ài)好者可能對(duì)這些消息不太滿意,因?yàn)?React 仍在繼續(xù)推進(jìn)對(duì)服務(wù)器端特性的支持。
其實(shí),SPA 并不適合描述這類應(yīng)用程序。任何認(rèn)為應(yīng)用和 API 應(yīng)該完全分開(kāi)的開(kāi)發(fā)者都可能不喜歡 React 正在推進(jìn)的方向。
use server 和 actions 引入了一個(gè)新的思維模式,在這一模式下,可以在服務(wù)器或?yàn)g覽器中無(wú)縫運(yùn)行代碼,除非明確指定其他方式。
這種新的思維模式通過(guò) actions 得到了擴(kuò)展,能夠處理待處理和錯(cuò)誤狀態(tài)。
然而,這個(gè)新模型在博客文章中解釋得并不清楚,容易讓 React 開(kāi)發(fā)者感到困惑。
這也可以理解,因?yàn)樾碌?React 文檔建議開(kāi)發(fā)者使用基于 React 的框架,而不是直接使用 React。但另一方面,這也使得直接使用 React 的開(kāi)發(fā)者面臨困難局面。
我們有了新的 hooks 和表單操作,可以直接從表單元素級(jí)別獲取表單狀態(tài)。
新的 API 可以通過(guò) use 函數(shù)調(diào)用來(lái)掛起功能,還提供了服務(wù)器組件。
React 團(tuán)隊(duì)需要付出大量努力來(lái)向新手程序員解釋這些復(fù)雜內(nèi)容。
但也有一些不錯(cuò)的方面。
可以告別 forwardRef,被 ref 取代
forwardRef 現(xiàn)在將被替換,你可以直接用 ref 傳遞組件元素。這是一個(gè)讓人意外的好變化。
可以直接使用 Context 而不是 Context.Provider
現(xiàn)在提供上下文時(shí),你無(wú)需使用 Context.Provider
,而是直接使用 Context
。示例如下:
const ThemeContext = createContext('');
function App({children}) {
return (
<ThemeContext value="dark">
{children}
</ThemeContext>
);
}
可以更方便地清理被卸載的 refs:
通過(guò)在組件卸載時(shí)清理關(guān)聯(lián)的 refs,可以確保沒(méi)有懸掛的引用或潛在的內(nèi)存泄漏。
<input
ref={(ref) => {
// 當(dāng) ref 被創(chuàng)建時(shí),執(zhí)行一些初始化操作
if (ref) {
// 初始化代碼,例如,添加事件監(jiān)聽(tīng)器或設(shè)置屬性
}
// 返回清理函數(shù),在元素被移除時(shí)調(diào)用
return () => {
// 清理代碼,例如,移除事件監(jiān)聽(tīng)器或重置屬性
};
}}
/>
可以在任何組件中定義 <meta> 標(biāo)簽
另一個(gè)值得注意的改進(jìn)是,現(xiàn)在支持從任意組件動(dòng)態(tài)更新 <meta> 標(biāo)簽。
import { Helmet } from "react-helmet";
function BlogPost({ post }) {
return (
<article>
<Helmet>
<title>{post.title}</title>
<meta name="author" content="Josh" />
<link rel="author" />
<meta name="keywords" content={post.keywords} />
</Helmet>
<h1>{post.title}</h1>
<p>Eee equals em-see-squared...</p>
</article>
);
}
可以在組件級(jí)別使用樣式表
現(xiàn)在,在組件級(jí)別添加樣式將不會(huì)出現(xiàn)任何問(wèn)題。React 將在顯示組件之前加載樣式表,這也為懶加載樣式提供了可能性:
function ComponentOne() {
return (
<Suspense fallback="loading...">
<link rel="stylesheet" href="foo" precedence="default" />
<link rel="stylesheet" href="bar" precedence="high" />
<article class="foo-class bar-class">
{...}
</article>
</Suspense>
)
}
可以預(yù)加載資源
在 React 19 中,你將能夠在組件中使用函數(shù)預(yù)加載資源,而不是在 HTML 中通過(guò) HTML 標(biāo)簽預(yù)加載。
import { prefetchDNS, preconnect, preload, preinit } from 'react-dom'
function MyComponent() {
preinit('https://.../path/to/some/script.js', {as: 'script' }) // loads and executes this script eagerly
preload('https://.../path/to/font.woff', { as: 'font' }) // preloads this font
preload('https://.../path/to/stylesheet.css', { as: 'style' }) // preloads this stylesheet
prefetchDNS('https://...') // when you may not actually request anything from this host
preconnect('https://...') // when you will request something but aren't sure what
}
基本的自定義元素支持
React 團(tuán)隊(duì)仍在努力支持 HTML 自定義元素。雖然目前還沒(méi)有針對(duì) React 19 beta 的官方測(cè)試結(jié)果,但根據(jù) React 博客的說(shuō)法,它是符合測(cè)試標(biāo)準(zhǔn)的。
PropTypes 被移除了
PropTypes 是 React 團(tuán)隊(duì)做出的一個(gè)奇怪決策,當(dāng)時(shí)他們完全忽略了 TypeScript 的存在。
幸運(yùn)的是,PropTypes 在 2017 年被棄用,現(xiàn)在處理它們的代碼已從 React 中移除。這意味著在代碼庫(kù)中保留這些怪物般的工具已經(jīng)沒(méi)有意義了。如果想要了解自己正在使用的類型,至少需要將代碼庫(kù)重寫(xiě)為 TypeScript。
如何為 React 19 做好準(zhǔn)備?
React 19 beta 已經(jīng)發(fā)布,但這并不意味著你必須立刻更新。我建議等待正式發(fā)布。然而,你可以先安裝 React 18.3.0。它和 18.2.0 類似,但會(huì)顯示關(guān)于在 React 19 中將被廢棄的功能的提示信息。
因此,你可以提前做好準(zhǔn)備。
你可以在 npm 上找到 React 19 beta 和 React 18.3.0 版本的構(gòu)建包。
React 19 beta 的源碼暫時(shí)不可用。