成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一篇教你如何升級到 React 18

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

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

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

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

安裝

使用 @rc標(biāo)簽來安裝最新版 React。

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

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

客戶端渲染 API 更新

當(dāng)你首次安裝 React 18 的時(shí)候,你會(huì)看到如下警告:

  • 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,會(huì)自動(dòng)啟用 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" />);

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

// Before
unmountComponentAtNode(container);

// After
root.unmount();

我們移除了 ReactDOM.render 函數(shù)的 callback,因?yàn)楫?dāng)使用 Susponse 的時(shí)候,它會(huì)有問題:

// 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 來實(shí)現(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,將會(huì)拋出警告:

  • renderToNodeStream:廢棄 ???。

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

  • renderToPipeableStream:新增 ?。

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

  • renderToReadableStream:新增 ?。

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

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

下面的 API 沒有變化:

  • renderToStaticNodeStream。

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

自動(dòng)批處理 Automatic Batching

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

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

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

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

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

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

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

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

嚴(yán)格模式 Strict Mode

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

這個(gè)功能會(huì)給 React 項(xiàng)目帶來非常好的體驗(yàn),但要求組件支持 state 不變的情況下,組件多次卸載和重載。

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

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

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

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

* 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)境

當(dāng)你第一次在測試用例中使用 createRoot時(shí)候,你會(huì)看到以下警告:

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

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

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

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

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

移除了 IE 支持

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

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

其它變更

  • 移除“setState on unmounted component” 警告[15]。
  • Susponse 不再強(qiáng)制需要 fallback 屬性[16]。
  • 組件支持 render undefined[17]。
  • 廢棄 renderSubtreeIntoContainer[18]。
  • 嚴(yán)格模式不再忽略自動(dòng)二次渲染組件的 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 不再強(qiáng)制需要 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]嚴(yán)格模式不再忽略自動(dòng)二次渲染組件的 log: https://github.com/reactwg/react-18/discussions/96。

責(zé)任編輯:姜華 來源: 前端技術(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

2020-01-13 10:00:32

升級Windows 10Windows

2022-10-08 15:07:06

ChatOps運(yùn)維

2016-07-22 09:09:00

Linux Mint 升級Linux Mint

2019-07-15 07:58:10

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

2022-08-04 08:17:27

React高階組件

2017-09-05 08:52:37

Git程序員命令

2015-07-29 10:21:03

微軟Windows 10升級

2013-11-27 09:38:11

OpenSUSE 13OpenSUSE 12

2021-07-29 07:55:20

React實(shí)踐代碼

2022-03-22 09:09:17

HookReact前端

2021-10-20 12:47:06

UbuntuUbuntu 21.1Linux

2022-08-28 20:34:42

LinuxLinux Mint

2017-03-09 17:02:23

UbuntuLinux升級

2022-02-12 19:30:22

KDE PlasmaPlasma桌面

2022-12-20 08:22:42

CommitMuation

2022-11-10 16:55:41

ReactFiber

2013-08-20 15:48:50

Fedora 18Fedora 19
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 一区二区免费视频 | 国产精品日韩欧美一区二区三区 | 午夜看片网站 | 神马久久春色视频 | 日韩精品激情 | 日韩中文字幕在线视频 | 成人在线视频一区二区三区 | 日韩三级在线 | 久久夜夜| 免费观看一级黄色录像 | www久久久| 成人综合一区二区 | 懂色av一区二区三区在线播放 | 99色在线| 成人午夜在线观看 | 99国内精品 | 天天看天天爽 | 91资源在线 | 日本一区二区三区精品视频 | 日本a视频 | 午夜久久久久久久久久一区二区 | 欧美成人一区二免费视频软件 | 91在线视频在线观看 | 极品粉嫩国产48尤物在线播放 | 亚洲成人一区二区三区 | 在线成人免费av | 精品伊人久久 | 99精品视频在线观看免费播放 | 91视频91| 亚洲国产精品99久久久久久久久 | 国产精品成人一区二区三区夜夜夜 | 久久www免费视频 | 久久国产精99精产国高潮 | 日本激情视频网 | 欧美精品成人一区二区三区四区 | 国产传媒在线观看 | 资源首页二三区 | 欧美video | 日韩在线免费 | 亚洲欧美在线观看 | 日韩精品视频一区二区三区 |