发布于 2026-01-06 1 阅读
0

React 18 升级指南和新功能 DEV's Worldwide Show and Tell Challenge Presented by Mux: Pitch Your Projects!

React 18 升级指南和新功能

由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!

作者:乔尔·阿德沃勒

介绍

由于库的更新经常包含对现有功能的彻底更改,甚至移除某些功能并添加其他功能,因此一些开发者可能会发现难以在不同版本的库之间进行过渡。为了获得最佳性能,最好使用最新版本的库。

要从React 17 迁移到 React 18,您可以创建一个新的 React 项目,也可以在现有项目中重新安装 React 。

本文将探讨React 18 的定义、React 17 存在的问题、React 18 的新特性,以及您应该使用最新版本的原因。为了更好地阅读本文,您需要熟悉 JavaScript、React 和 NPM。

React 18 是什么?

在深入了解“React 18 的新特性”之前,我们先来看一下 React 18 的含义。React
库的任何稳定版本,从 18.0.0 开始,但不包括 19.0.0,都被称为 React 18。

React 18 的发布在 React 应用中引入了并发渲染。React 一直以来负责 DOM 渲染,并为开发者提供工具来控制和跟踪组件的生命周期。凭借一些新功能,React 18 现在可以根据客户端设备调整渲染过程。

升级到 React 18

React 社区提供了多种安装选项。要在您的应用程序中安装 React 18,您可以使用 CDN URL 作为 HTML script 标签中的 source(src) 属性。

  <!-- Load React. -->
  <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
  <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
  <!-- Load our React component. -->
  <script src="app.js"></script>
</body>
Enter fullscreen mode Exit fullscreen mode

在工作目录的终端中执行以下命令,即可使用 NPM 或 Yarn 为单页应用和打包应用升级或安装 React 18。
对于 NPM:

npm install react react-dom
Enter fullscreen mode Exit fullscreen mode

对于纱线:

yarn add react react-dom
Enter fullscreen mode Exit fullscreen mode

以上命令将自动检测并安装或升级开发环境中的最新 React 和 React DOM 版本。

React 17 的问题

React 社区注意到该库存在一些需要改进的问题。**如果 React 17 运行完美,就没有必要发布 React 18 及更高版本。

根据React 18.0.0 的更新日志,该版本解决了 React 17 或更早版本中的以下问题:

  • 如果返回值为 ,则渲染会抛出错误undefined:当组件返回值为 时undefined,应用程序将崩溃。

应用程序显示以下错误:

图片首次错误

您还会在控制台中看到以下错误:

图片 secondError

  • setState尝试更新已卸载组件的状态时,React 可能会发出内存泄漏警告:

图片 thirdError

  • 严格模式下控制台日志抑制:根据社区反馈,我们注意到,在使用严格模式时抑制控制台日志消息会造成混乱,因为只会显示一条消息而不是两条。

  • 内存消耗:React 17 及更早版本存在内存泄漏问题,尤其是在未挂载的组件中。


GitHub 支持横幅

React 18 中发生了哪些变化?

React 18 更加强调应用程序并发性。这一理念体现在诸如 Automatic Batching、Transition 和 Suspense 等功能,以及 createRoot、hydrateRoot、renderToPipeableStream 和 renderToReadableStream 等 API 中。此外,它还包含 useId、useTransition、useDeferredValue、useSyncExternalStore 和 useInsertionEffect 等 hooks,以及对严格模式的更新和对某些功能的ReactDOM.render弃用renderToString

让我们深入了解一下这些变化👀:

客户端渲染

升级后,您可能需要留意以下主机警告:

图片客户端错误

如果您继续使用ReactDOM.render()React 17 支持的 API,您将会看到此警告。通常,我们会导入一个组件并将其渲染到 id 为 app 的 div 元素中。

import ReactDOM from 'react-dom';
import App from 'App';

const app = document.getElementById('app');

ReactDOM.render(<App />, app);
Enter fullscreen mode Exit fullscreen mode

在 React 18 中,如下面的代码示例所示,我们使用createRoot()从“react-dom/client”导入的 API:

import {createRoot}from 'react-dom/client';
import App from 'App';

const app = document.getElementById('app');

// create a root
const root = createRoot(app);

//render app to root
root.render(<App />);
Enter fullscreen mode Exit fullscreen mode

水合作用

React 17 使用了ReactDOM.hydrate()API 来实现水合渲染,如下面的代码示例所示:

import * as ReactDOM from 'react-dom';
import App from 'App';

const app = document.getElementById('app');

// Render with hydration.
ReactDOM.hydrate(<App tab="home" />, app);
Enter fullscreen mode Exit fullscreen mode

在 React 18 中,水合作用使用hydrateRoot()从“react-dom/client”导入的 API,不再需要render()像以下代码片段中那样使用单独的方法:

import {hydrateRoot} from 'react-dom/client';

import App from 'App';

const app = document.getElementById('app');

const root = hydrateRoot(app, <App tab="home" />);
Enter fullscreen mode Exit fullscreen mode

渲染回调

你可以在渲染根组件时传递一个回调函数,以便它在组件渲染或更新后执行。

在 React 17 的 render 方法中,你可以将回调函数作为第三个参数传递,如下面的代码片段所示:

import * as ReactDOM from 'react-dom';
import App from 'App';

const app = document.getElementById('app');

ReactDOM.render(app, <App tab="home" />, function() {
  // Called after initial render or any update.
  console.log('Rendered or Updated').
});
Enter fullscreen mode Exit fullscreen mode

React 18不允许使用回调函数,因为它会影响应用程序的运行时,尤其是在渐进式或部分水合的情况下。您可以改用 ref 回调,setTimeout或者requestIdleCallback在根元素上使用回调,如下面的代码示例所示:

import {createRoot} from 'react-dom/client';

function App({ callback }) {
  // Callback will be called when the div is first created.
  return (
    <div ref={callback}>
      <h1>Hello World</h1>
    </div>
  );
}

const app = document.getElementById("root");

const root = createRoot(app);
root.render(<App callback={() => console.log("Rendered or Updated")} />);
Enter fullscreen mode Exit fullscreen mode

自动批处理

在 React 17 版本之前,状态更新仅在 React 事件处理程序中进行批量处理。因此,任何在事件处理程序之外进行的状态更新都会导致重新渲染,这需要 React 执行额外的后台任务。例如:

const handleClick = () => {
  setFirstState(1);
  setSecondState(2);
}
Enter fullscreen mode Exit fullscreen mode

在上述代码片段中,React 只会在事件回调函数结束时所有状态都已更改后才会重新渲染。否则,对于 Promise、原生事件或 React 事件处理程序之外的状态更新,情况就会有所不同。例如:

fetch(https://api.com’).then(() => {
  setFirstState("1");
  setSecondState("2");
})

//OR

setTimeout(() => {
  setFirstState("1");
  setSecondState("2");
})
Enter fullscreen mode Exit fullscreen mode

在上面的代码片段中,React 会在每次状态更新时重新渲染。

React 18 中的APIcreateRoot()允许批量处理所有状态更新,无论这些更新发生在应用程序的哪个位置。React 会在所有状态更新完成后重新渲染页面。

由于这是一个重大变更,您可以使用 API 停止自动批处理flushSync()

import { flushSync } from 'react-dom';

function handleClick() {
  flushSync(() => {
    setFirstState("1");
  });

  flushSync(() => {
    setSecondState("2");
  });

}
Enter fullscreen mode Exit fullscreen mode

在上面的代码片段中,每个实例都会flushSync()更新状态并允许 React 重新渲染。

过渡

您可以使用转换来区分需要紧急/立即状态更新的资源和不需要状态更新的资源。

搜索栏的功能就是一个很好的例子。当用户输入搜索词时,你可能需要显示一些视觉反馈。但是,你不希望搜索在用户输入完毕之前就开始。

import { startTransition } from 'react';

// Urgent: Show what was currently typed
setSearchCurrentValue(input);


startTransition(() => {
  // Not-urgent: Show what was finally typed
  setSearchFinalValue(input);
});
Enter fullscreen mode Exit fullscreen mode

在代码片段中,setTimeout()我们没有使用会延迟状态更新的方法,而是使用了startTransition()监听状态更新的方法。setSearchCurrentValue()这种方法只更新与我们希望用户立即获得的反馈相关的状态,而另一种setSearchFinalValue()方法则更新我们希望在用户完成输入后最终用于执行搜索的状态。

与 不同setTimeoutstartTransition更新可以被中断,可以跟踪待处理的更新,并且会立即执行。

停止支持 Internet Explorer

React 社区已停止对 Internet Explorer 的支持,这意味着只有 React 17 及之前版本的浏览器功能才能在 Internet Explorer 上运行。诸如多任务处理、循环加载等现代浏览器功能PromiseObject.assign无法Symbol在 Internet Explorer 中实现。

React 18 相对于 React 17 的优势

即使了解了React 17 和 React 18 之间的区别,您可能仍然不确定是切换到 React 18 还是继续使用 React 17。

如果新版本不能比以前的版本带来更多好处,就不会受到欢迎。

并发是 React 18 的主要优势之一。它是一个全新的概念,而非一项现有功能,它使运行在 React 18 及更高版本上的 React 应用能够优化其在客户端设备上的性能。

React 18 通过在卸载时清除后台任务来增强内存管理,并降低内存泄漏的风险。

结论

阅读本教程后,您应该能够更新 React 版本并重构代码库,从而无缝使用React 18 。

要获取有关变更和新版本的最新信息,您还应该密切关注 React 库的变更日志以获取更新,并与 React 社区保持联系。


Discord 横幅


别再浪费时间在应用程序里到处复制粘贴表格代码了!

隆重推出这款基于 React 的无头解决方案,助您构建简洁高效的CRUD应用。有了 refine,您可以确保代码库始终保持整洁,告别冗余代码。

尝试改进以快速构建您的下一个CRUD项目,无论是管理面板、仪表板、内部工具还是店面。


优化博客徽标

refine是一个基于 React 的开源框架,用于构建不受限制的 CRUD 应用。它采用无头设计,可以与任何您喜欢的自定义设计UI 框架无缝集成。为了方便起见,它还预装了对Ant Design System、Material UI 和 Mantine UI 的集成。

它能将您的开发速度提高 3 倍,同时又不影响样式、自定义和项目工作流程的自由度。

访问refine GitHub 存储库以获取更多信息、演示、教程和示例项目。

文章来源:https://dev.to/refine/react-18-upgrade-guide-and-new-features-28dm