3 月 8 日,React 团队发布了 React 18 RC(Release Candidate)。最新版本带来了许多新功能,可以改变许多应用程序中的编码模式。它带来了一些性能改进,我将在本博客中介绍这些改进。

并发

并发是系统的一种属性,其中多个进程同时执行,并且可能会或可能不会相互交互。太复杂了?让我们分解一下。假设正在进行一场比赛。现在,并发是有多少人在平行赛道上参加一场比赛。

并发

并发是 React 18 引入的一个新特性。它是一种新的幕后机制,使 React 能够同时准备多个版本的 UI

在这种机制下,与以前的情况不同,React 可能会开始渲染,中间暂停一些关键任务,然后再次恢复渲染。唯一要记住的是,它也可能完全放弃进程渲染。即使渲染中断,React 也能保证 UI 看起来是一致的。

这使 React 能够在后台准备屏幕 - 不会阻塞新线程!

服务端渲染的悬念

服务端渲染的悬念

React 在 Next.js、Relay、Hydrogen 或 Remix 等服务器端渲染框架中带来了 Suspense 的特性。React 18 引入:有悬念 的服务端代码拆分,服务端 Streaming 渲染

自动配料

批处理是 React 将多个状态更新分组到一个重新渲染中以实现更好的性能优化的现象。

动图 配料

在 React 18 之前,对基于反应的事件处理程序执行批量更新。但是对于**promises、setTimeouts、本机事件处理程序或任何其他事件,**没有执行批量更新。React 18 也针对上述情况执行自动批量更新。

让我们使用代码来理解这一点。

setTimeout(() => {
  setCount(count => count + 1);
  setFlag(flag => !flag);
  // React will only re-render once at the end (that's batching!)
}, 1000);

同样,上述代码的行为与此相同:

fetch(/*...*/).then(() => {
  setCount(counter => counter + 1);
  setFlag(flag => !flag);
  // React will only re-render once at the end (that's batching!)
})

如果您不想批处理,可以使用ReactDOM.flushSync(). 让我们用一点代码来理解

import { flushSync } from 'react-dom'; // Note: react-dom, not react

function handleFlushesClick() {
  flushSync(() => {
    setCounter(counter => counter + 1);
  });
  // React has updated the DOM by now
  flushSync(() => {
    setFlag(flag => !flag);
  });
  // React has updated the DOM by now
}

过渡

此功能区分紧急和非紧急更新。紧急更新是需要立即响应的更新。紧急更新包括点击、按下、键入等操作——需要立即响应或用户希望 UI 立即响应的操作。 屏幕上不会显示任何中间值。

动图 过渡示例

一个真实的例子

考虑一个现实生活中的例子,让我们考虑一个去抖动的 typeahead。现在,当您输入输入时,您希望输入框反映输入的值。但是,您希望结果立即出现吗?没有权利!它会去抖动,然后你会得到结果。因此,从您输入输入到您收到建议之间有一段过渡时间。这个时间框架将用于过渡。

通常,为了获得最佳用户体验,单个用户输入应导致紧急和非紧急更新。

import {startTransition} from 'react';

// Urgent: Show what was typed
    setInputValue(input);`

// Mark any state updates inside as transitions
  startTransition(() => {
     // Transition: Show the autosuggestion based on the input 
        value
      setSearchQuery(input);
});

动图 搜索栏

另一个实时示例

const [isPending, startTransition] = useTransition()

这里 useTransition 钩子有 2 个被解构的参数。

isPending: 表示 UI 更新是否仍处于过渡状态

startTransition:执行事务代码的函数。

function handleClick() {
   startTransition(() => {
     setTab('comments');
   });
}

当您想从照片选项卡切换到评论选项卡时,会调用此函数。

```<Suspense fallback={}><div style={{ opacity: isPending ? 0.8 : 1 }}>{tab === ‘photos’ ? : }