開發(fā)者對(duì) React 19 Beta 發(fā)布感到困惑
React 19 beta 終于來了,但其中一些非常棒的功能卻因困惑和溝通不暢而黯然失色。
React 19 beta 可以隨時(shí)發(fā)布,但現(xiàn)在選擇在 2024 年 3 月 25 日發(fā)布實(shí)屬最佳,因?yàn)殚_發(fā)世界暫時(shí)沒有其他重大事件。
編譯器尚未到來
一些開發(fā)者對(duì)這次發(fā)布持樂觀態(tài)度,但也有許多人擔(dān)心此次版本中沒有提到編譯器。
React 編譯器是 React 團(tuán)隊(duì)長時(shí)間實(shí)驗(yàn)的工具,目前用于運(yùn)行 Instagram,并且預(yù)計(jì)很快會(huì)發(fā)布。開發(fā)者們對(duì)編譯器的期望很高,因?yàn)樗鼘p少手動(dòng)記憶化的需求,這是一項(xiàng)耗時(shí)且容易出錯(cuò)的 React 修補(bǔ)工作。有了編譯器,React 將更善于判斷何時(shí)需要更新 UI,何時(shí)不需要,從而提升性能。
但我們?nèi)圆淮_定編譯器何時(shí)能正式發(fā)布。可能在五月,也許是 2024 年或 2026 年?希望它能在新 GTA 發(fā)布前上線!
你將享受更多的服務(wù)器端支持
SPA(單頁應(yīng)用)愛好者可能對(duì)這些消息不太滿意,因?yàn)?React 仍在繼續(xù)推進(jìn)對(duì)服務(wù)器端特性的支持。
其實(shí),SPA 并不適合描述這類應(yīng)用程序。任何認(rèn)為應(yīng)用和 API 應(yīng)該完全分開的開發(fā)者都可能不喜歡 React 正在推進(jìn)的方向。
use server 和 actions 引入了一個(gè)新的思維模式,在這一模式下,可以在服務(wù)器或?yàn)g覽器中無縫運(yùn)行代碼,除非明確指定其他方式。
這種新的思維模式通過 actions 得到了擴(kuò)展,能夠處理待處理和錯(cuò)誤狀態(tài)。
然而,這個(gè)新模型在博客文章中解釋得并不清楚,容易讓 React 開發(fā)者感到困惑。
這也可以理解,因?yàn)樾碌?React 文檔建議開發(fā)者使用基于 React 的框架,而不是直接使用 React。但另一方面,這也使得直接使用 React 的開發(fā)者面臨困難局面。
我們有了新的 hooks 和表單操作,可以直接從表單元素級(jí)別獲取表單狀態(tài)。
新的 API 可以通過 use 函數(shù)調(diào)用來掛起功能,還提供了服務(wù)器組件。
React 團(tuán)隊(duì)需要付出大量努力來向新手程序員解釋這些復(fù)雜內(nèi)容。
但也有一些不錯(cuò)的方面。
可以告別 forwardRef,被 ref 取代
forwardRef 現(xiàn)在將被替換,你可以直接用 ref 傳遞組件元素。這是一個(gè)讓人意外的好變化。
可以直接使用 Context 而不是 Context.Provider
現(xiàn)在提供上下文時(shí),你無需使用 Context.Provider
,而是直接使用 Context
。示例如下:
const ThemeContext = createContext('');
function App({children}) {
return (
<ThemeContext value="dark">
{children}
</ThemeContext>
);
}
可以更方便地清理被卸載的 refs:
通過在組件卸載時(shí)清理關(guān)聯(lián)的 refs,可以確保沒有懸掛的引用或潛在的內(nèi)存泄漏。
<input
ref={(ref) => {
// 當(dāng) ref 被創(chuàng)建時(shí),執(zhí)行一些初始化操作
if (ref) {
// 初始化代碼,例如,添加事件監(jiān)聽器或設(shè)置屬性
}
// 返回清理函數(shù),在元素被移除時(shí)調(diào)用
return () => {
// 清理代碼,例如,移除事件監(jiān)聽器或重置屬性
};
}}
/>
可以在任何組件中定義 <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)任何問題。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 中通過 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 自定義元素。雖然目前還沒有針對(duì) React 19 beta 的官方測試結(jié)果,但根據(jù) React 博客的說法,它是符合測試標(biāo)準(zhǔn)的。
PropTypes 被移除了
PropTypes 是 React 團(tuán)隊(duì)做出的一個(gè)奇怪決策,當(dāng)時(shí)他們完全忽略了 TypeScript 的存在。
幸運(yùn)的是,PropTypes 在 2017 年被棄用,現(xiàn)在處理它們的代碼已從 React 中移除。這意味著在代碼庫中保留這些怪物般的工具已經(jīng)沒有意義了。如果想要了解自己正在使用的類型,至少需要將代碼庫重寫為 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í)不可用。