React 18 有哪些新功能?

2025-06-07

React 18 有哪些新功能?

虽然还有很多功能即将推出,但我认为分享其顶级新功能可能会很有趣。

自动配料

React 中的批处理是指将多个状态更新组合成一次重新渲染。

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    setCount(c => c + 1); // Does not re-render yet
    setFlag(f => !f); // Does not re-render yet

    // React will only re-render once at the end (that's batching!)

  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

在这个例子中,组件只会在调用handleClick后渲染一次,尽管我们可能认为setCountsetClicked会触发两次重新渲染。

虽然目前这种方法效果很好,

如果您在不同的上下文(例如承诺回调)中调用多个状态更新。

// Promise
fetchSomething().then(()=> {
    setCount(count+1);
    setFlag(true);
})

//callback or timeout
setTimeOut(()=>{
    setCount(count + 1);
    setFlag(true);
})
Enter fullscreen mode Exit fullscreen mode

React 不会将这两个更新批量合并为一个,并且当只需要一个时,您将获得两次重新渲染。

使用 React 18,所有这些用例现在都将被覆盖,并且无论上下文如何,状态更新都将自动批处理。

import {unstable_batchedUpdates} from 'react-dom';
unstable_batchedUpdates(() => {
    setCount(count + 1);
    setFlag(true);
})

//React 18 will do it for you by default. 
Enter fullscreen mode Exit fullscreen mode

这可能会让你想起正在执行此操作的unstable_batchedUpdates,现在,React 将默认为你执行此操作。

如何停止批处理?

如果您不希望这些更新被批量处理,则需要使用flushSync,它会在每次运行完您传递给它的函数时重新渲染您的组件。

import {flushSync} from 'react-dom';

function handleClick(){
    flushSync(()=> {
            setCount(count + 1);
    });
    // React has re-render

    flushSync(()=> {
            setFlag(true);
    });
    // React will re-render
}
Enter fullscreen mode Exit fullscreen mode

因此,通过以下方式,您的组件将渲染两次,而不是一次。

过渡

这是一个非常重要的新功能,它允许您“告诉 React哪些更新是紧急的,哪些不紧急”。

一个很好的例子是搜索输入应该过滤掉元素列表。

因此,如果您要更新搜索输入,您希望它的值在我们输入时发生变化,尽管搜索结果可能会在一秒钟内出现

当我们完成打字时。

import {startTransition} from 'react';

//Urgent : Update input value as type
setInputValue(input);

startTransition(()=>{
    //Secondary: Show the search results
    setSearchQuery(input)
});
Enter fullscreen mode Exit fullscreen mode

在这里,我们可以将输入值的变化标记为紧急更新,并将元素过滤为次要的,也称为转换。

转换可能会因紧急更新而中断,并且不再相关的先前转换将被忽略。

这使得用户界面只显示其最新状态,并跳过可能较慢的二次更新和转换

计算并有时返回不相关的中间状态。

正如您在此处看到的,我们将输入值更改标记为紧急,并在转换中运行我们的二次更新,因为它可能会触发缓慢的计算,并可能在我们键入时冻结或减慢整个用户体验。

startTransition非常适合任何“你想移动到后台”的更新,例如缓慢而复杂的渲染任务,或者

更新依赖于获取数据,而由于网络速度较慢,这可能需要一些时间。

Suspense 和服务端渲染

SSR(服务器端渲染)的工作方式是渲染所有

首先在服务器上加载组件,然后将结果作为 HTML 发送到浏览器。

之后,JavaScript 会照常加载,并且 HTML 会通过所谓的“水合”神奇地变得具有交互性。

这会将您的静态 HTML 元素转换为您所了解的动态 React 组件。

问题?

这种方法的主要问题是,只要 JavaScript 尚未获取、加载,并且 HTML 尚未水化,您的页面就不会具有交互性。

为了解决这个瀑布问题,React 18 现在为 SSR 提供​​了两个新功能:

流式 HTML 和选择性水合

流式 HTML

流式 HTML 意味着服务器可以在组件渲染时发送它们。

这通过使用 Suspense 来实现,您可以指定应用程序的哪些部分需要更长时间才能加载以及哪些部分应该直接呈现。

<Page>
    <Article />
    <Suspense fallback={<Loader />}>
         <Comments />   
    </Suspense>
</Page>
Enter fullscreen mode Exit fullscreen mode

如果你想到一篇带有评论的文章,​​其中文章是页面的关键部分,你可以说加载文章,但不要

等待评论准备好将 HTML 发送到浏览器。

您可以使用Suspense来显示旋转器,一旦评论准备好,

React 将发送新的 HTML 位来替换原来的微调器。

选择性水合

选择性补水效果极佳。

以前,您必须等待每个组件渲染完毕才能开始水合,但现在使用 Suspense 包裹的组件将不再阻止水合。

如果我们回到我们的文章页面,我们用 Suspense 包裹的评论将不会阻止文章和其他组件进行水化。

一旦浏览器获取其内容和 JavaScript 代码,每个就绪的组件将开始水化,注释也将开始水化。

选择性水合最重要的特点

如果你碰巧在某个组件完全水化之前与它进行交互,比如你点击了某个地方,那么 React 就会优先考虑这个组件的水化。

这确保了一旦我们能够水合相关成分,就可以重复最关键的相互作用,确保它

在其他人之前补充水分。

感谢您的阅读。

如果您确实从本文中学到了一些新东西,请保存它并与您的同事分享。

您可以通过 Twitter@muditit 联系我

文章来源:https://dev.to/muditdev/what-s-new-in-react-18-32m4
PREV
VSCode 的 5 个完美替代品!1. Visual Studio 2. Visual Studio Code Insiders 3 Visual Studio Codium 4 Visual Studio Codespaces(付费版)5 Eclipse Theia
NEXT
使用 Docker 将 React 应用容器化并投入生产