自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一篇教你如何升級到 React 18

開發(fā) 前端
今天,我們發(fā)布了 React 18 RC 版本。正如我們在 React Conf上分享的那樣,React 18 基于 concurrent 模式,帶來了更多能力,同時提供了漸進升級的方法。在這篇文章中,我們會一步一步的帶您升級到 React 18。

這是 React 官方 2022.03.08 發(fā)表的文章《How to Upgrade to the React 18 Release Candidate[1]》的譯文,通過本文,可以對 React 18 的新特性有一個全面的認知。

接下來,我還會翻譯其它幾篇比較重要的 React 18 文章,以便以更好的姿勢使用 React 18,關(guān)注不迷路。

今天,我們發(fā)布了 React 18 RC 版本。正如我們在 React Conf[2] 上分享的那樣,React 18 基于 concurrent 模式,帶來了更多能力,同時提供了漸進升級的方法。在這篇文章中,我們會一步一步的帶您升級到 React 18。

安裝

使用 @rc標簽來安裝最新版 React。

## npm
$ npm install react@rc react-dom@rc

## yarn
$ yarn add react@rc react-dom@rc

客戶端渲染 API 更新

當你首次安裝 React 18 的時候,你會看到如下警告:

  • ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it’s running React 17. Learn more: https://reactjs.org/link/switch-to-createroot[3]。

React 18 提供了更合理的初始化 API,使用該 API,會自動啟用 concurrent 模式:

// Before
import { render } from 'react-dom';
const container = document.getElementById('app');
render(<App tab="home" />, container);

// After
import { createRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = createRoot(container);
root.render(<App tab="home" />);

同時我們將卸載方法從 unmountComponentAtNode 修改為 root.unmount:

// Before
unmountComponentAtNode(container);

// After
root.unmount();

我們移除了 ReactDOM.render 函數(shù)的 callback,因為當使用 Susponse 的時候,它會有問題:

// Before
const container = document.getElementById('app');
ReactDOM.render(<App tab="home" />, container, () => {
console.log('rendered');
});
// After
function AppWithCallbackAfterRender() {
useEffect(() => {
console.log('rendered');
});
return <App tab="home" />
}
const container = document.getElementById('app');
const root = ReactDOM.createRoot(container);
root.render(<AppWithCallbackAfterRender />);

最后,如果你使用 hydration 來實現(xiàn)了 SSR,需要將 hydrate 替換為 hydrateRoot:

// Before
import { hydrate } from 'react-dom';
const container = document.getElementById('app');
hydrate(<App tab="home" />, container);
// After
import { hydrateRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = hydrateRoot(container, <App tab="home" />);
// Unlike with createRoot, you don't need a separate root.render() call here.

更多信息可見 Replacing render with createRoot[4]。

SSR API 更新

在 React 18 中,為了支持服務(wù)端的 Suspense 和流式 SSR,優(yōu)化了 react-dom/server 的 API。

使用以下 API,將會拋出警告:

  • renderToNodeStream:廢棄 ???。

相反,對于 Node 環(huán)境中的流式傳輸,請使用:

  • renderToPipeableStream:新增 ?。

我們還引入了一個新的 API,以在現(xiàn)代邊緣運行時環(huán)境支持流式 SSR 和 Suspense,例如 Deno 和 Cloudflare workers:

  • renderToReadableStream:新增 ?。

下面的兩個 API 可以繼續(xù)使用,但是不支持 Suspense:

  • renderToString:限制 ??。
  • renderToStaticMarkup:限制 ??。

下面的 API 沒有變化:

  • renderToStaticNodeStream。

更多信息可見Upgrading to React 18 on the server[5]、New Suspense SSR Architecture in React 18[6]。

自動批處理 Automatic Batching

批處理是指:React 將多個狀態(tài)更新,聚合到一次 render 中執(zhí)行,以提升性能。

在 React 18 之前,只能在 React 自己的事件機制中使用批處理,而在 Promise、setTimeout、原生事件等場景下,是不能使用批處理的。

React 18 支持了更多場景下的批處理,以提供更好的性能。

// 在 React 18 之前,只有 React 事件,才會使用批處理
function handleClick() {
setCount(c => c + 1);
setFlag(f => !f);
// React 只會 re-render 一次,這就是批處理
}
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React 會 render 兩次,每次 state 變化更新一次
}, 1000);

使用 createRoot初始化 React 18 之后,所有的狀態(tài)更新,會自動使用批處理,不關(guān)心應(yīng)用場景。

// React 18 之后,Promise、setTimeout、原生事件中,都會自動批處理
function handleClick() {
setCount(c => c + 1);
setFlag(f => !f);
// React 只會 re-render 一次,這就是批處理
}
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React 只會 re-render 一次,這就是批處理
}, 1000);

這是一個 break change,但是我們希望這能提升你的產(chǎn)品性能。當然,你仍然可以使用 flushSync 來手動取消批處理,強制同步執(zhí)行:

import { flushSync } from 'react-dom';

function handleClick() {
flushSync(() => {
setCounter(c => c + 1);
});
// React 更新一次 DOM
flushSync(() => {
setFlag(f => !f);
});
// React 更新一次 DOM
}

更多信息可見 Automatic batching for fewer renders in React 18[7]。

三方庫 API

在 React 18 中,我們和三方庫作者合作,定義了一些新的 API,以滿足三方庫在 concurrent 模式下特定場景的訴求。比如 styles 管理、外部狀態(tài)管理、可訪問性(accessibility)等場景。

為了支持 React 18,一些三方庫可能需要用到下面的 API:

  • useId 是一個新的 Hook,支持在客戶端和服務(wù)端生成唯一的 ID,同時避免 hydration 的不兼容。它可以解決在 React 17 。 及更低版本一直存在的問題。在 React 18 中,這個問題尤為重要,因為流式 SSR 返回的 HTML 片段是無序的。更多信息可見 Intent to Ship: useId[8]。
  • useSyncExternalStore是一個新的 Hook,允許外部狀態(tài)管理器,強制立即同步更新,以支持并發(fā)讀取。這個新的 API 推薦用于所有 。 React 外部狀態(tài)管理庫。詳情見 useSyncExternalStore overview post[9]、useSyncExternalStore API details[10]。
  • useInsertionEffect是一個新的 Hook,它可以解決 CSS-in-JS 庫在渲染中動態(tài)注入樣式的性能問題。除非你已經(jīng)構(gòu)建了一個 CSS-in-JS 庫,否則我們不希望你使用它。這個 Hook 執(zhí)行時機在 DOM 生成之后,Layout Effect 執(zhí)行之前。更多信息可見 Library Upgrade Guide for style[11]。

React 18還為 concurrent 渲染引入了新的 API,例如 startTransition 和 useDeferredValue,在即將發(fā)布的穩(wěn)定版本中會分享更多相關(guān)內(nèi)容。

嚴格模式 Strict Mode

未來,我們希望添加一個功能,允許 React 保存組件的狀態(tài),但移除 UI 部分。比如在返回舊的頁面時,React 立即恢復(fù)之前的內(nèi)容。為此,React 將使用之前保留的狀態(tài)重新加載組件。

這個功能會給 React 項目帶來非常好的體驗,但要求組件支持 state 不變的情況下,組件多次卸載和重載。

為了檢查出不合適的組件寫法,React 18 在開發(fā)模式渲染組件時,會自動執(zhí)行一次卸載,再重新加載的行為,以便檢查組件是否支持 state 不變,組件卸載重載的場景。

在以前,React 加載組件的邏輯為:

* React mounts the component.
* Layout effects are created.
* Effect effects are created.

在 React 18 嚴格模式的開發(fā)環(huán)境,React 會模擬卸載并重載組件:

* React mounts the component.
* Layout effects are created.
* Effect effects are created.
* React simulates unmounting the component.
* Layout effects are destroyed.
* Effects are destroyed.
* React simulates mounting the component with the previous state.
* Layout effect setup code runs
* Effect setup code runs

更多信息可見:Adding Strict Effects to Strict Mode[12] 、How to Support Strict Effects[13]。

配置測試環(huán)境

當你第一次在測試用例中使用 createRoot時候,你會看到以下警告:

  • The current testing environment is not configured to support act(…)。

為了修復(fù)這個問題,你需要在執(zhí)行用例之前設(shè)置 globalThis.IS_REACT_ACT_ENVIRONMENT為 true。

// In your test setup file
globalThis.IS_REACT_ACT_ENVIRONMENT = true;

這個標記告訴 React,它在一個類似單元測試的環(huán)境中運行。如果你忘了使用 act,React 將打印一些有用的警告。你也可以將標志設(shè)置為 false 來告訴 React 不需要 act。這對于模擬瀏覽器環(huán)境的端到端測試很有用。當然,我們希望測試庫會自動為您加上這個配置。例如,下一個版本的 React Testing Library 內(nèi)置了對 React 18 的支持,無需任何額外配置。

更多信息可見:More background on the the act testing API and related changes[14]。

移除了 IE 支持

在此版本中,React 將放棄對 Internet Explorer 的支持。我們進行此更改是因為 React 18 中引入的新功能是基于現(xiàn)代瀏覽器開發(fā)的,部分能力在 IE 上是不支持的,比如 microtasks。

如果您需要支持 Internet Explorer,我們建議您繼續(xù)使用 React 17。

其它變更

  • 移除“setState on unmounted component” 警告[15]。
  • Susponse 不再強制需要 fallback 屬性[16]。
  • 組件支持 render undefined[17]。
  • 廢棄 renderSubtreeIntoContainer[18]。
  • 嚴格模式不再忽略自動二次渲染組件的 log[19]。

參考資料

[1]How to Upgrade to the React 18 Release Candidate: https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html。

[2]React Conf: https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html。

[3]https://reactjs.org/link/switch-to-createroot: https://reactjs.org/link/switch-to-createroot。

[4]Replacing render with createRoot: https://github.com/reactwg/react-18/discussions/5。

[5]Upgrading to React 18 on the server: https://github.com/reactwg/react-18/discussions/22。

[6]New Suspense SSR Architecture in React 18: https://github.com/reactwg/react-18/discussions/37。

[7]Automatic batching for fewer renders in React 18: https://github.com/reactwg/react-18/discussions/21。

[8]Intent to Ship: useId: https://github.com/reactwg/react-18/discussions/111。

[9]useSyncExternalStore overview post: https://github.com/reactwg/react-18/discussions/70。

[10]useSyncExternalStore API details: https://github.com/reactwg/react-18/discussions/86。

[11]Library Upgrade Guide for style: https://github.com/reactwg/react-18/discussions/110。

[12]Adding Strict Effects to Strict Mode: https://github.com/reactwg/react-18/discussions/19。

[13]How to Support Strict Effects: https://github.com/reactwg/react-18/discussions/18。

[14]More background on the the act testing API and related changes: https://github.com/reactwg/react-18/discussions/102。

[15]移除“setState on unmounted component” 警告: https://github.com/reactwg/react-18/discussions/82。

[16]Susponse 不再強制需要 fallback 屬性: https://github.com/reactwg/react-18/discussions/72。

[17]組件支持 render undefined: https://github.com/reactwg/react-18/discussions/75。

[18]廢棄 renderSubtreeIntoContainer: https://github.com/facebook/react/pull/23355。

[19]嚴格模式不再忽略自動二次渲染組件的 log: https://github.com/reactwg/react-18/discussions/96。

責任編輯:姜華 來源: 前端技術(shù)磚家
相關(guān)推薦

2022-03-24 12:28:03

React 17React 18React

2022-04-18 08:57:32

React 18前端

2011-09-27 09:13:16

Ubuntu 11.0

2022-10-08 15:07:06

ChatOps運維

2016-07-22 09:09:00

Linux Mint 升級Linux Mint

2020-01-13 10:00:32

升級Windows 10Windows

2019-07-15 07:58:10

前端開發(fā)技術(shù)

2022-08-04 08:17:27

React高階組件

2021-07-29 07:55:20

React實踐代碼

2022-03-22 09:09:17

HookReact前端

2013-11-27 09:38:11

OpenSUSE 13OpenSUSE 12

2015-07-29 10:21:03

微軟Windows 10升級

2017-09-05 08:52:37

Git程序員命令

2013-08-20 15:48:50

Fedora 18Fedora 19

2022-12-20 08:22:42

CommitMuation

2022-11-10 16:55:41

ReactFiber

2022-08-28 20:34:42

LinuxLinux Mint

2021-10-20 12:47:06

UbuntuUbuntu 21.1Linux

2017-03-09 17:02:23

UbuntuLinux升級

2022-02-12 19:30:22

KDE PlasmaPlasma桌面
點贊
收藏

51CTO技術(shù)棧公眾號