背景:

React官方在2022年3月29日React18版本正式发布了。

可以在官网看到,react 17 的发布时间是 2020 年 10 月 20 号,距离 React 18 发布足足间隔一年半,并且v17中只有三个小版本,分别是17.0.017.0.117.0.2

并且一直到React18发布,React17都没有任何更新,可以说React17只是作为React18的垫脚石。

升级原因:

  1. React18的并发更新和自动批处理可以提升项目性能。

2. 提高项目的兼容性

在项目使用React17的时候,如果依赖的组件使用的React18版本可能导致项目因为版本不匹配而发生错误甚至奔溃(亲测有效)。而项目如果使用了React18,依赖的其他组件使用React18或者React17都可以很好的兼容。

升级:

  1. 新项目: 直接使用npm 或这 yarn安装即可。
npm install react react-dom --save
yarn install react react-dom --save
  1. 老项目: 将package.json中的react版本改为18,删除node_modules文件

再执行npm install即可。

项目中的需要修改的地方:

1. 挂在组件时:ReactDOM.render

// React 17
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';const root = document.getElementById('root')!;//React 18
// React 18
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';const root = document.getElementById('root')!;ReactDOM.createRoot(root).render(<App />);

2. 卸载组件时: unMountComponentAtNode升级为root.unmount

// React 17
ReactDOM.unmountComponentAtNode(root);// React 18
root.unmount();

3. 删除了render中的回调函数。

如果项目中有在render中用到了回调函数,迁移到对应组件的useEffect中即可。

// React 17
const root = document.getElementById('root')!;
ReactDOM.render(<App />, root, () => {console.log('渲染完成');
});// React 18
const AppWithCallback: React.FC = () => {useEffect(() => {console.log('渲染完成');}, []);return <App />;
};
const root = document.getElementById('root')!;
ReactDOM.createRoot(root).render(<AppWithCallback />);

4. typeScript中需要手动定义children

在项目中定义props类型的时候,如果需要获取字组件children需要显示的定义它。

5. setState自动批处理

什么是批处理?

批处理就是多个状态更新合并成一个次更新。(视图层将多次渲染合并成一次渲染)

在React18以前

我们只在React18中进行批处理。默认情况下,在promisesetTimeout原生事件处理函数中、或任何其它事件内的更新都不会进行批处理。

在React18以后

所有更新都会自动进行批处理。多次更新将会合并成一次更新,从而降低渲染次数提高性能。

改动点:

如果项目中有通过promise、setTimeout、原生事件处理函数去解决批处理的问题在React18中将不会生效了。

如果再想退出批处理,需要使用flushSync

import React, { useState } from 'react';
import { flushSync } from 'react-dom';const App: React.FC = () => {const [count1, setCount1] = useState(0);const [count2, setCount2] = useState(0);return (<divonClick={() => {flushSync(() => {setCount1(count => count + 1);});// 第一次更新flushSync(() => {setCount2(count => count + 1);});// 第二次更新}}><div>count1: {count1}</div><div>count2: {count2}</div></div>);
};export default App;

6. react组件返回空值

在react17中,如果你需要返回一个空组件,ract只允许你返回null。如果你显示的返回了undifined控制台则会在运行时抛出一个错误。

在react18中,不在见出啊因返回undifined而导致奔溃。即能返回null,也能返回undifned。

Concurrent Mode(并发模式)

并发模式可帮助应用保持响应,并根据用户的设备性能和网速进行适当的调整,该模式通过使渲染可中断来修复阻塞渲染限制。在 Concurrent 模式中,React 可以同时更新多个状态。

react17 和 react18的区别就是:从同步不可中断更新变成了异步可中断更新

开启并发模式:

在React18中提供了新的root Api,我们只需要把render改成ReactDOM.createRoot(root).render(<App />) 就可以开启并发模式。

开启并发模式就一定开启并发更新吗?

No!在React18中开启并发模式不一定开启并发更新,而是否开启并发更新的依据是是否使用并发特性

并发特性指的是开启并发模式才能使用的特性,比如下面介绍的:

  1. startTranstion
  2. useTranstion
  3. useDeferredValue

结论:

并发更新的意义就是交替执行不同的任务,当预留的时间不够用时,React将线程控制交给浏览器,等待下一帧时间的到来,然后继续被中断的工作。

  • 并发模式是实现并发更新的基本前提。
  • 时间切片是实现并发更新的基本手段。

Transition:

在大屏幕视图更新的时,startTransition 能够保持页面有响应,这个 api 能够把 React 更新标记成一个特殊的更新类型 transitions ,在这种特殊的更新下,React 能够保持视觉反馈和浏览器的正常响应。

1. startTransition:

startTransition(scope)

  • scope 是一个回调函数,里面的更新任务都会被标记成过渡更新任务,过渡更新任务在渲染并发场景下,会被降级更新优先级,中断更新。

使用:

startTransition(()=>{/* 更新任务 */func()
})

startTranstion的回调包裹的setState触发的渲染标记为不紧急渲染。这些渲染可能被其他紧急渲染所抢占。

2. useTranstion

在低优先级还没执行的时候,怎么知道过渡任务处于什么状态,这时候就可以使用useTranstion这个Hooks。useTranstion执行返回一个数组,数组有两个状态值。

第一个状态值: 当处于过渡状态的标记。

第二个状态值: 可以理解为startTranstion,将任务标记为过渡任务。

import { useTranstion } from 'react';const [isPending, startTrastion] = useTranstion();

3. useDeferredValue

返回一个延时响应的值可以让一个state延时生效,只有当前没有紧急更新的任务时,该值才会变为最新的值。和startttanstion一样都是标记为非紧急更新。

useTranstion和useDeferredValue异同:

相同点: useDeferredValue本质上和内部实现与useTranstion一样都是标记成了过度更新任务。

不同点:useTranstion是把startTranstion内部的更新任务变成了过度任务transtion,而useDeferredValue是把原值通过过度任务得到新的值,这个值作为延时状态,一个是处理逻辑,一个是生产一个新的状态。

例子

输入框输入一个内容,更新10000条列表内容。在chrome仓库看执行栈。

使用并发特性:

我们可以看到使用并发特性

此时我们的任务被拆分到每一帧不同的task中,JS脚本执行的时间大体在5ms左右,这样浏览器就有剩余的时间执行页面的样式布局和页面重绘。

使用普通更新:

我们可以看到只有一次页面的重绘,其他几次输入都因为输入触发js的执行而阻塞了更新。

新的api

一, useId

const id = useId();

支持同一个组件在客户端和服务端生成相同的唯一的 ID,避免 hydration 的不兼容,这解决了在 React 17 及 17 以下版本中已经存在的问题。因为我们的服务器渲染时提供的 HTML 是无序的,useId 的原理就是每个 id 代表该组件在组件树中的层级结构。

二, useSyncExternalStore

useSyncExternalStore是一个新的api,经历了一次修改,由useMutableSource改变而来,主要用来解决外部数据撕裂的问题。

三, useInsertionEffect

在dom生成之后,useLayoutEffect之前,它的工作原理大致合useLayoutEffect相同,只是此时无法访问DOM节点的引用,一般用于提前注入<style>脚本。

react17-react18

参考地址: react/CHANGELOG.md at main · facebook/react · GitHub

React18升级和React18新特性相关推荐

  1. 【JavaSE】Java9Java10Java11新特性(687~717)

    687.复习:动态代理 688.复习:Lambda表达式 689.复习:函数式接口 690.复习:方法引用与构造器引用 691.复习:Stream API 692.复习:Optional类的使用 69 ...

  2. React Native 0.59.x新特性解读

    概述 众所周知,在现在的前端技术开发栈中,跨平台开发是一个重要的课题,不管是老牌的Hybird还是最近流行的RN.Weex还是Flutter,不得不说,现在前端和客户端的界限越来越模糊. 最近在写&l ...

  3. react18 新特性 useTransition

    react 18环境说明 脚手架 安装 create-react-app npm install -g create-react-app create-react-app demo-react 环境配 ...

  4. php v5.,PHP V5.3 中的新特性,第 5 部分- 从 PHP V5.2 升级到 PHP V5.3

    PHP V5.3 中的新特性,第 5 部分: 从PHP V5.2 升级到 PHP V5.3 1 2 3 4 5 下一页 PHP V5.3 将于不久后发布."PHP V5.3 中的新特性&qu ...

  5. Spring Cloud Greenwich 新特性和F版升级分享

    来源:https://dwz.cn/LkwPsmut 前几天介绍了,关于Spring Cloud Greenwich版本发布的官方博客翻译:Spring Cloud Greenwich.RELEASE ...

  6. Angular4.0.0正式发布,附新特性及升级指南

    作者|孙薇编辑|尾尾经历了6个RC版本之后,Angular项目组终于在今天发布了新版,即 正式版 Angular 4.0.0.新版的 Angular 有哪些值得关注的点,究竟带来了哪些新特性?如何升级 ...

  7. 赶紧看一下mysql8.0版本的新特性,你的数据库是不是该升级了

    这里写目录标题 前言 mysql8.0的新特性 1.账户安全 2.优化器索引 2.1.隐藏索引(invisible) 2.2.降序索引 2.3.函数索引 3.SQL语句增强 4.新增数据分析函数 5. ...

  8. 全面升级 | 阿里云中间件推出3款新品和3项产品新特性,加速企业中台落地

    自2015年年底,阿里巴巴对外宣布全面启动2018年中台战略,构建符合DT时代的更具创新性.灵活性的"大中台.小前台"组织机制和业务机制后,承载中台战略的企业级互联网架构已在各行业 ...

  9. Spring Cloud Greenwich 新特性和F升级分享

    2019.01.23 期待已久的Spring Cloud Greenwich 发布了release版本,作为我们团队也第一时间把RC版本替换为release,以下为总结,希望对你使用Spring Cl ...

最新文章

  1. HDU 4505 小Q系列故事——电梯里的爱情
  2. Vue组件多次点击报错Avoided redundant navigation to current location: “/profile“.
  3. fundamental-react在POC中的一个应用
  4. orm框架选型问题_ORM问题
  5. 文本二叉树折半查询及其截取值
  6. 通过8个技巧让你成为一个超强的Linux终端用户
  7. 这款耳机堪比千元级的AirPods
  8. 小程序监听android返回键,如何监听小程序返回按钮事件?
  9. inner join 重复数据_Ramp;Python Data Science 系列:数据处理(2)
  10. 携号转网全面启动后,新诈骗套路也跟上了!一招教你识别!
  11. 删除镜像文件,显示操作无法完成,因为文件已经在system中打开。解决办法
  12. 深度Linux挂载盘
  13. Python爬取中国票房网所有电影片名和演员名字,爬取齐鲁网大陆所有电视剧名称...
  14. 我在汉语编程留言,确引来了一顿臭骂,气愤之后,贴出来让大家评,目的让更多的人知道forth
  15. Python数据挖掘:利用聚类算法进行航空公司客户价值分析
  16. day56 JavaScript
  17. 一个好的学习算法的网站
  18. 微信朋友圈广告投放审核服务器,微信朋友圈广告位投放文案审核规范
  19. 神一样的编程语言? -- 发现一个编程语言“shen”
  20. 蓝牙协议栈消息的关联

热门文章

  1. cascades文档翻译——HomeScreen
  2. 【技巧】Vivado 仿真器simulation显示模拟波形图(非数字波形)
  3. 金山词霸的词库读取程序
  4. 读论文 第二天:Sparse Inertial Poser: Automatic 3D Human Pose Estimation from Sparse IMUs
  5. Skype交互过程分析
  6. 凯立德2018android零售版,凯立德2018冬季版C-CAR车机零售版懒人包C1204-C7P08-3J21J24
  7. 广州app定制:IO定制游APP
  8. 2021PMP®项目管理认证招生简章
  9. MySQL COMPACT栏格式导致输出乱码
  10. Qt之简单图片浏览器