Cómo actualizar a React 18

Esta es la traducción del artículo " Cómo actualizar a React 18 Release Candidate " publicado por React oficial el 8 de marzo de 2022. A través de este artículo, puede tener una comprensión completa de las nuevas características de React 18.

A continuación, también traduciré varios otros artículos más importantes de React 18 para usar React 18 en una mejor postura y prestar atención para no perderse.

Hoy lanzamos el lanzamiento de React 18 RC. Como compartimos en React Conf , React 18 se basa en el modo concurrente, lo que brinda más capacidades y proporciona un método para actualizaciones incrementales. En este artículo, lo guiaremos paso a paso para actualizar a React 18.

Instalar en pc

Use la @rcetiqueta para instalar la última versión de React

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

## yarn
$ yarn add react@rc react-dom@rc
复制代码

Actualizaciones de la API de representación del lado del cliente

Cuando instale React 18 por primera vez, verá la siguiente advertencia

ReactDOM.render ya no es compatible con React 18. Utilice createRoot en su lugar. Hasta que cambie a la nueva API, su aplicación se comportará como si estuviera ejecutando React 17. Más información: reactjs.org/link/switch…

React 18 proporciona una API de inicialización más razonable. Con esta API, el modo concurrente se habilita automáticamente:

// 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" />);
复制代码

Al mismo tiempo, unmountComponentAtNodemodificamos a root.unmount:

// Before
unmountComponentAtNode(container);

// After
root.unmount();
复制代码

Eliminamos la ReactDOM.renderfunción callbackporque era problemática al usar 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 来实现了 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

SSR API 更新

在 React 18 中,为了支持服务端的 Suspense 和流式 SSR,优化了 react-dom/server 的 API。

使用以下 API,将会抛出警告:

  • renderToNodeStream:废弃 ⛔️️

相反,对于 Node 环境中的流式传输,请使用:

  • renderToPipeableStream:新增

我们还引入了一个新的 API,以在现代边缘运行时环境支持流式 SSR 和 Suspense,例如 Deno 和 Cloudflare workers:

  • renderToReadableStream:新增

下面的两个 API 可以继续使用,但是不支持 Suspense:

  • renderToString:限制 ⚠️
  • renderToStaticMarkup:限制 ⚠️

下面的 API 没有变化:

  • renderToStaticNodeStream

更多信息可见Upgrading to React 18 on the serverNew Suspense SSR Architecture in React 18

自动批处理 Automatic Batching

批处理是指:React 将多个状态更新,聚合到一次 render 中执行,以提升性能。

在 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 之后,所有的状态更新,会自动使用批处理,不关心应用场景。

// 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,但是我们希望这能提升你的产品性能。当然,你仍然可以使用 flushSync 来手动取消批处理,强制同步执行:

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

三方库 API

在 React 18 中,我们和三方库作者合作,定义了一些新的 API,以满足三方库在 concurrent 模式下特定场景的诉求。比如 styles 管理、外部状态管理、可访问性(accessibility)等场景。

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

  • useId 是一个新的 Hook,支持在客户端和服务端生成唯一的 ID,同时避免 hydration 的不兼容。它可以解决在 React 17 及更低版本一直存在的问题。在 React 18 中,这个问题尤为重要,因为流式 SSR 返回的 HTML 片段是无序的。更多信息可见 Intent to Ship: useId

  • useSyncExternalStore是一个新的 Hook,允许外部状态管理器,强制立即同步更新,以支持并发读取。这个新的 API 推荐用于所有 React 外部状态管理库。详情见 useSyncExternalStore overview postuseSyncExternalStore API details

  • useInsertionEffect是一个新的 Hook,它可以解决 CSS-in-JS 库在渲染中动态注入样式的性能问题。除非你已经构建了一个 CSS-in-JS 库,否则我们不希望你使用它。这个 Hook 执行时机在 DOM 生成之后,Layout Effect 执行之前。更多信息可见 Library Upgrade Guide for style

React 18还为 concurrent 渲染引入了新的 API,例如 startTransitionuseDeferredValue,在即将发布的稳定版本中会分享更多相关内容。

严格模式 Strict Mode

未来,我们希望添加一个功能,允许 React 保存组件的状态,但移除 UI 部分。比如在返回旧的页面时,React 立即恢复之前的内容。为此,React 将使用之前保留的状态重新加载组件。

这个功能会给 React 项目带来非常好的体验,但要求组件支持 state 不变的情况下,组件多次卸载和重载。

为了检查出不合适的组件写法,React 18 在开发模式渲染组件时,会自动执行一次卸载,再重新加载的行为,以便检查组件是否支持 state 不变,组件卸载重载的场景。

在以前,React 加载组件的逻辑为:

* React mounts the component.
    * Layout effects are created.
    * Effect effects are created.
复制代码

在 React 18 严格模式的开发环境,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 ModeHow to Support Strict Effects

配置测试环境

当你第一次在测试用例中使用 createRoot时候,你会看到以下警告:

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

为了修复这个问题,你需要在执行用例之前设置 globalThis.IS_REACT_ACT_ENVIRONMENTtrue

// In your test setup file
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
复制代码

Esta etiqueta le dice a React que se está ejecutando en un entorno similar a una prueba de unidad. React imprimirá algunas advertencias útiles si olvida usar act. También puede establecer el indicador en falso para decirle a React que no se requiere actuar. Esto es útil para pruebas de extremo a extremo que simulan un entorno de navegador. Por supuesto, esperamos que la biblioteca de prueba agregue automáticamente esta configuración. Por ejemplo, la próxima versión de React Testing Library tiene soporte integrado para React 18 sin ninguna configuración adicional.

Puede encontrar más información aquí: Más antecedentes sobre la API de prueba de acto y los cambios relacionados

Se eliminó el soporte de IE

En esta versión, React dejará de ser compatible con Internet Explorer. Hicimos este cambio porque las nuevas características introducidas en React 18 se basan en el desarrollo de navegadores modernos y algunas capacidades no son compatibles con IE, como las microtareas.

Si necesita admitir Internet Explorer, le recomendamos que continúe usando React 17.

Otros cambios

Supongo que te gusta

Origin juejin.im/post/7078601734716653604
Recomendado
Clasificación