官⽅警告,react18已经来了
18他来了
什么,react18都来啦,不敢相信,react17都还没捂热,18突然就来了,没有⼀点点防备,就是这么惊喜,react官⽹已经放出react18的介绍了,还是不信的话,你点点链接瞧瞧吧。看⽇⼦是8号发布的,⼤致瞄了⼀眼,我就赶紧去npm搜⼀下版本,18.0.0-alpha已经在11个⼩时之前放上去了。现在只是尝鲜版本,根据官⽅介绍,18正式版本推出之前,还会有数⽉的打磨,要在⼯作中要⽤到还需要耐⼼等待,但是对于react技术栈的同学来说,还是要乘早关注起来,如果能加⼊社区提供⼀些正向的反馈,那更是极好的。说了这么多,我们接下来看下官⽅多react18的介绍吧。
新特新
1.Automatic batching
这个特性简单来说,就是⾃动批量更新,对于熟悉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>
)
;
}
这段代码我直接拷贝Dan Abramov对于Automatic batching特性说明的演⽰代码(下⾯也是-_-),从注释来看,handleClick只会触发⼀次渲染,为什么这么设计呢,⽤Dan的例⼦解释:饭店的服务⽣不会你点了⼀个菜就会去通知厨房吧,⽽是点完了之后再⼀次性告诉厨房,这么做的⼀个最⼤好处就是性能更好,接下来再看下⼀段代码:
function App() {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
function handleClick() {
fetchSomething().then(() => {
// React 17 and earlier does NOT batch these:
setCount(c => c + 1); // Causes a re-render
setFlag(f => !f); // Causes a re-render
});
}
return (
<div>
<button onClick={handleClick}>Next</button>
<h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
</div>
);
}
这⼀次会渲染两次,如果你深⼊react原理了解,也不会很差异这种结果。简单来说,异步任务执⾏的时候其实已经不在react的上下⽂环境了,react内部是通过⼀个标识来标记是否需要批量更新的,render开始,标记为true,commit之后,标记为false,异步任务再执⾏,其实是在commit之后的,那么由于标记为false,因此就不⾛批量了。⼤概就是这么个意思,有兴趣的可以去深挖⼀下其中的实现细节。不光是setTimeout,⽤dan的描述来说,Updates inside of promises, setTimeout, native event handlers, or any other event were not batched in React by default,因此promise/setTimeout/原⽣事件这些触发的渲染都不会⾛批量,当然这些都是在18版本之前,18版本是怎样的呢,还是上代码吧:setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React will only re-render once at the end (that's batching!)
}, 1000);
这⾥的异步任务就完成了⾃动的批量更新,当然在18版本要开启这个功能的话,需要使⽤ateRoot去挂载我们的应⽤,如果我们还是使⽤der的话,就不会启⽤Automatic batching了。
Automatic batching看起来很⾹,但是如果在⼀些场景我不想⽤呢,官⽅也提供了解决办法,请看例⼦:
import { flushSync } from 'react-dom'; // Note: react-dom, not react
function handleClick() {
flushSync(() => {
setCounter(c => c + 1);
});
// React has updated the DOM by now
flushSync(() => {
setFlag(f => !f);
});
// React has updated the DOM by now
}
react work group还对Automatic batching做了很多的探讨,包括对class/hooks的影响,有兴趣的可以。
看完对Automatic batching的说明后,还想补充⼀点,react18版本前的blocking和concurrent模式其实已经⽀持Automatic batching of multiple setStates了,⼤家可以去试试效果。最后再说⼀下unstable_batchedUpdates这个api,在18版本之前,如果我们要⼿动批量,需要借助它去
react to后面接什么实现,在18版本会依然⽀持。
2.startTransition
这是⼀个崭新的api,⼲什么的呢,就是让我们的应⽤交互更加丝滑,⽤来提升体验的,⾸先我们来了解⼀下它要解决⼀个什么样的问题。官⽅⼯作⼩组⾥⾯的讨论描述了⼀个场景,就是⼀个输⼊框,接收⽤户输⼊,然后去筛选列表项,场景很常见,但是会有⼀个性能隐患,输⼊这个操作可能会触发⼤量的更新,导致页⾯卡顿,给⽤户直观的感受就是输⼊框有点卡,不能实时显⽰输⼊的字符了,那么要怎么破呢,这让我想到了react的并发渲染模式,不就是要来解决这种优先级的问题么,但是遗憾的是⼀直处于实验当中,还不能安⼼⽤在⼯作中,不扯远了,还是回到这个api上来,通过代码我们对⽐⼀下:
// Urgent: Show what was typed
setInputValue(input);
// Not urgent: Show the results
setSearchQuery(input);
import { startTransition } from 'react';
// Urgent: Show what was typed
setInputValue(input);
// Mark any state updates inside as transitions
startTransition(() => {
// Transition: Show the results
setSearchQuery(input);
});
代码⽚段1就是我们的常⽤写法,⽤户输⼊就更新输⼊框的状态值进⾏实时显⽰输⼊,然后去筛选列表,setInputValue和setSearchQuery是同时执⾏的;代码⽚段2就使⽤了startTransition这个api,将setSearchQuery包裹其中,实现⼿动的渲染任务优先级排列,那么此时setInputValue的更新就⾼于setSearchQuery,因此⽤户的输⼊响应就能得到保证,从⽽实现丝滑的体验,官⽅还将其于setTimeout进⾏了对⽐,这⾥就不展开介绍了,⼤家。
3.New Suspense SSR Architecture
react18对SSR的性能进⾏了新的改进,引⼊了pipeToNodeWritable这个新的API,这个API可以替换renderToString,同时renderToNodeStream被标记为Deprecated,为什么会有这些改动呢,官⽅给出了解释:
renderToString: Keeps working (with limited Suspense support).
renderToNodeStream: Deprecated (with full Suspense support, but without streaming).
pipeToNodeWritable: New and recommended (with full Suspense support and streaming)
出现了两个需要注意的单词:Suspense和streaming,Suspense这个组件在16.6.0被正式提出来,以前主要配合React.lazy⽤来异步加载组件的,⽽streaming就是指的React Server Components,现在react
18对这两者的⽀持就更加完善了,因此react18的SSR将让⽤户更快的看见界⾯,更早的交互。
react18的SSR相⽐以前的SSR,有啥优势呢,那我们先看下传统的SSR流程吧:
On the server, fetch data for the entire app.
Then, on the server, render the entire app to HTML and send it in the response.
Then, on the client, load the JavaScript code for the entire app.
Then, on the client, connect the JavaScript logic to the server-generated HTML for the entire app (this is “hydration”).
以上四步必须严格按照流程⼀步步来,就像waterfall⼀样,如果其中哪⼀步慢了,就会阻塞后⾯的流程,这样⽤户就需要忍受更长的⽩屏时间,因此如果将上⾯四个步骤打散成⼀个个⼩的任务单元,那么先完成的任务就可以尽快呈现到⽤户⾯前,这样体验⾃然就更优了,这也是react18对Suspense和streaming改进的动⼒所在,dan对这⼀部分有详细的介绍,点了解更多。
渐进式升级
每当版本发⽣了重⼤更新,升级就是每个框架必须要考虑的⼀件事情,对于开发者来讲,升级不能对我现有的项⽬造成影响吧,放⼼,react 考虑得⽐我们更多,其实vue也是⼀样,都提供了渐进式平滑得升级策略。react官⽅说了,放⼼升级吧,只需对应⽤程序代码进⾏很少的更改或不做任何更改,其实不光是react18,react16到17,对于升级其实都是成本很⼩的。
社区和react18⼯作⼩组
React 18 Working Group也是随着react18版本的到来⽽成⽴的⼀个组织,⼯作职能跟w3c的working group类似,作为联系社区与react18的桥梁,充分吸收来⾃各⽅的意见和讨论,⼤家有兴趣可以去了解⼀下。
发布计划
React 18 Library Alpha (Available now)
React 18 Public Beta (Months)
React 18 RC (Months)
React 18 (2-4 weeks after RC)
官⽅推出的发布计划,⼤家拭⽬以待吧。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。