前言
React 18为并发渲染api奠定了基础,未来的React特性将在此基础上构建。这个版本主要关注性能的改进和渲染引擎的更新。
- 快速指引 Category | Feature | | ---------------------- | -------------------------------------------------------------------------------- | | 主题 | Concurrent React 并发 | | 支持 | Automatic Batching, Transitions, Suspense on the server | | API更新 | createRoot, hydrateRoot, renderToPipeableStream, renderToReadableStream | | Hooks | useId, useTransition, useDeferredValue, useSyncExternalStore, useInsertionEffect | | 更新 | Strict mode | | 弃用 | ReactDOM.render, renderToString
如何升级到React 18
从npm或yarn安装React 18和React DOM
npm install react react-dom
使用createRoot代替render
在index.js中,ReactDOM.render更新为ReactDOM.createRoot去创建root,并使用root -渲染你的应用
React 17 -
import ReactDOM from 'react-dom';
import App from 'App';
const container = document.getElementById('app');
ReactDOM.render(<App />, container);
React 18 -
import ReactDOM from 'react-dom';
import App from 'App';
const container = document.getElementById('app');
// create a root
const root = ReactDOM.createRoot(container);
//render app to root
root.render(<App />);
核心:并发
假设我们需要给两个人打电话——爱丽丝和鲍勃。在非并发设置中,一次只能呼叫一个——首先呼叫Alice,结束,然后再呼叫Bob。
当与Alice呼叫需要等待很长时间时(例如on-hold),其会浪费很多时间。如下图所示:
但是
在并发设置中,如果呼叫Alice的过程中需要等待,那可以先呼叫Bob。这意味着可以同时有两个或更多的并发调用,并决定哪个调用更重要。
类似地,在具有并发渲染的React 18中,React可以中断、暂停、恢复或放弃渲染。这使得React能够快速响应用户交互。在React 18之前,渲染是一个单一的、不间断的、同步的事务,一旦渲染开始,就不能被中断。
并发性是React呈现机制的基本更新。并发性允许React中断呈现。React 18介绍了并发渲染的基础,并发渲染支持Suspense、流服务器渲染和转换等新特性。
新功能:批处理
React 18具有自动批处理功能。
在React中,当调用setState时,批处理有助于减少状态改变时重新呈现的数量。以前,是在事件处理程序中响应批处理状态更新,例如:
const handleClick = () => {
setCounter();
setActive();
setValue();
}
//re-rendered once at the end.
但是,在事件处理程序之外发生的状态更新不是批处理的。比如,有一个promise或进行网络调用,状态更新将不是批处理的。如-
fetch('/network').then( () => {
setCounter(); //re-rendered 1 times
setActive(); //re-rendered 2 times
setValue(); //re-rendered 3 times
});
//Total 3 re-renders
React 18引入了自动批处理功能,允许所有的状态更新——即使在promise、settimeout和事件回调中也是批处理的。这大大减少了React在后台需要做的工作。React将等待微任务完成后再重新渲染。
但如果想不使用这个功能,可以调用flushSync
新功能: Transitions
Transitions可用于标记不需要紧急进行更新的UI。例如:当在预先输入字段中输入时,会发生两件事——一个闪烁的光标显示输入内容的视觉反馈,以及一个搜索功能在后台搜索输入的数据。
向用户显示视觉反馈是重要的,因此是紧急的。搜索不是那么紧急,因此可以标记为非紧急。这些非紧急更新称为Transitions。通过将非紧急的UI更新标记为“Transitions”,React将知道哪些更新应该优先,从而更容易优化渲染并摆脱陈旧的渲染。
可以使用startTransition将更新标记为非紧急更新。下面是一个使用transitions -标记的typeahead组件的例子
import { startTransition } from 'react';
// Urgent: Show what was typed
setInputValue(input);
// Mark any non-urgent state updates inside as transitions
startTransition(() => {
// Transition: Show the results
setSearchQuery(input);
});
和debouting/setTimeout的不同
- startTransition立即执行,不像setTimeout
- setTimeout有一个保证的延迟,而startTransition的延迟取决于设备的速度和其他紧急渲染。
- 与setTimeout不同,startTransition更新可以被中断,并且不会冻结页面。
- React可以在标记为startTransition时为您跟踪挂起状态。
新特性:服务器 Suspense
React 18介绍:
服务器上的代码分割与Suspense
服务器上的流渲染
客户端渲染vs服务器渲染
客户端渲染流程:
为了优化用户体验,避免用户黑屏,可以使用服务器呈现。服务器呈现是在服务器上呈现React组件的HTML输出并从服务器发送HTML的一种技术。这可以让用户在JS包加载时以及应用程序交互之前查看一些UI。
服务器渲染流程:
服务器呈现进一步增强了加载页面的用户体验,并减少了交互时间。一个缓慢的组件会使整个页面变慢。这是因为服务器渲染是全有或全无-你不能告诉React延迟加载一个慢的组件,也不能告诉React为其他组件发送HTML。
React 18在服务器端增加了Suspense, Suspense组件中包装应用程序的慢速部分,告诉React延迟慢速组件的加载。这也可以用来指定加载时显示的加载状态。
在React 18中,一个慢的组件不需要减慢整个应用的渲染速度。使用Suspense,你可以告诉React先发送其他组件的HTML,连同占位符的HTML一起,比如加载旋转器。然后,当慢速组件准备好并获取其数据时,服务器呈现程序将在同一流中弹出其HTML。
通过这种方式,用户可以尽早地看到页面的框架,并随着HTML的增加而逐渐显示出更多的内容。所有这些都发生在页面加载JS或React之前,从而显著改善了用户体验和用户感知的延迟。
Strict模式
React 18中的 Strict模式将模拟安装、卸载和重新安装组件的状态。Strict模式将确保组件对多次安装和卸载的效果有弹性。
更多内容请查看:dev.to/shrutikapoo…