千呼万唤始出来,React18

1,308 阅读4分钟

笔者承认这里有点标题党了,因为目前React发布的18还是属于RC版本。

什么是RC版本

在软件行业经常出现发布的是RC版本,比如iOSwindows,包括我们经常所使用的React或者其他NPM的packages,其实RC的全称是Release CandidateCandidate是候选人的意思,笔者这里给出一张表格,来比较下常见的alphabetaRCRelease版本之间的区别

版本名称介绍说明
alpha内测版内部测试版本
beta公测版Beta阶段会一直加入新的功能
RC候选版几乎就不会加入新的功能了,而主要着重于除错
Release正式版稳定版本

当然,未必是所有的厂商和团队都遵循这么一个规范,但是基本大部分比较正规的软件厂商或者开源社区,还是符合这个表格的。这里另外给大家安利一个Semantic Versioning 2.0.0 语义化版本规范,像我们前端开发经常使用的antd,在发布活动中就是践行这么一个规范的。如果有读者在团队中也做内外部组件库或者开源活动,不妨参考下。

React 18带来了什么

以下是React工作小组在React-18的讨论里面的内容,传送门

开箱即用的改进

  • 自动批处理减少渲染
  • Supsense的SSR支持
  • 修复Suspense行为问题

并发特性

  • startTransition:在昂贵的状态转换期间保持 UI 响应。
  • useDeferredValue 推迟更新屏幕上不太重要的部分。
  • :协调加载指示器出现的顺序。
  • 通过选择性水化流式传输 SSR:让应用加载并更快地进行交互。

文档中重点提到了一个,可以在局部开启这一特性,未必需要在全局开启。

\

我们接下来几期内容分别就以上更新内容来聊一聊,大家记得点个关注哦,避免错失后面的更新内容哦

案例:自动批处理

开启这一个特性的前提是使用React18,在ReactDOM入口处进行调整,比如以Create-React-App脚手架生成的项目为例

这里的变化是原来使用的ReactDOM.render,像这样

ReactDOM.render(<App/>,document.getElementById('root'));

然后我们就拿官方的Demo来讲下

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

  function handleClick() {
    fetchSomething().then(() => {
      // React 18 and later DOES batch these:
      setCount(c => c + 1);
      setFlag(f => !f);
      // 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>
  );
}

从概念上来说,一组React将多个状态更新放入一次渲染中的操作,被称为批处理。通常,当同一个点击事件中带有两个、或两个以上的状态更新时,那么React会将它们作为一次性的重新渲染进行批处理。例如,在上面的官方demo代码段正在运行时,进行一次单击时,尽管在后台设置为两个状态,但是React也只会执行一次性的代码渲染。

在自动批处理特性的加持下,就达到了提升性能的目的,而在之前的版本中,这里会执行两次渲染。

但是如果我们真的是像把两次操作分开执行,那应该怎么办呢?我们可以借助ReactDOM的一个API。

import React, {useState} from 'react';
import {flushSync} from "react-dom";

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

  function handleClick() {
    flushSync(() => {
      setCount(c => c + 1);

    });
    flushSync(() => {
      setFlag(f => !f);
    });

  }
  console.log('render');

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

如果我们的handleClick不使用FlushSync处理,那么点击按钮,仅会进行一次渲染。

批处理的特性同样在SetTimeout等场景下也适用。

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

接下来的几期内容我们会继续讲下18版本中的其他特性升级。跟其他前端框架不同的是,React在版本升级过程中所做的破坏性改动还是相对很少的,工作组对API的变动相对比较谨慎,所以不管是学习还是生产项目的迁移,风险和代价相对小很多。大家也不用抱怨说,哎呀,学不动了,学习这种技术管理的态度和敬畏心也是大家提高能力很重要的一部分哦。

Drop IE,利好 or 利空?

这次升级,React放弃了对IE的支持,不知道大家心里怎么想?其实Antd在5.x版本的设计公告中,也说了即将彻底放弃对IE的支持,包括IE11,当然Edge还是支持的。从笔者这么多年的从业经验来看,放弃IE是利大于弊的。然后如果你接手了一个历史遗留项目,又想从坑里爬出来的话,可能会有点难受。开源中国有篇公告称,苹果、谷歌、微软、火狐合力解决Web兼容性问题,不知道对我们来说是不是个利好哦。

历史的车轮永远会无情的向前滚,碾压一切不符合时代的东西。

感谢大家的陪伴。如果喜欢,不妨给笔者点个赞哦,关注下哦

参考文档:

  1. React 18 讨论 github.com/reactwg/rea…