react18已经来了

react18他来了

react17都还没捂热,react18突然就来了,没有一点点防备,react官网已经放出react18的介绍了官宣介绍。说了这么多,我们接下来看下官方多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版本要开启这个功能的话,需要使用ReactDOM.createRoot去挂载我们的应用,如果我们还是使用ReactDOM.render的话,就不会启用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版本之前,如果我们要手动批量,需要借助它去实现,在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,现在react18对这两者的支持就更加完善了,因此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)
复制代码

官方推出的发布计划,大家拭目以待吧。

作者:putao
链接:https://juejin.cn/post/6971655993390317598
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容