当前位置: 首页 > news >正文

React 18的新特新

React 18 最新的特性
批处理文件
在同一个 函数中, 调用多次 useState 也只是会更新一次

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

  function handleClick() {
    setCount(c => c + 1); // 不触发re-render
    setFlag(f => !f); // 不触发re-render
    // 在调用结束是只触发一次re-render(这就是batching)
  }
  
  return <button onClick={handleClick}>Next</button>;
}

但是在React 18以前,对于在异步回调中调用的updates,React Batching将无法生效:

function handleClick() {
  fetchSomething().then(() => {
  setCount(c => c + 1); // 触发re-render
  setFlag(f => !f); // 再次触发re-render
  });
}

这是因为在React 18之前,React只在事件处理程序期间批量更新。默认情况下,React不会对promise、setTimeout或任意event事件中的更新进行批处理。
在 React 18 版本 的这个flushSync 就可以达到批量更新

import { flushSync } from 'react-dom';
flushSync(() => {
setCount(c => c + 1); 
setFlag(f => !f); 
});

批量更新 但是render 值渲染一次, 节省了 dom的渲染性能
更新状态
2.1 紧急更新(Urgent updates):反映直接的交互,如输入、点击、按键按下等等。
2.2 过渡更新(Transition updates):将UI从一个视图过渡到另一个视图。
输入、点击、按键按下等需要立即响应以符合人类的物理认知,符合人的直觉。但是过渡更新却不同,用户不会期望看到中间的转换过程(只需要结果),因此可能不需要立即更新视图。
在React 18以前的版本所有的更新都会认为是紧急更新。而startTransition提供api给用户来手动将某些更新标记为非紧急更新,从而避免浪费时间去渲染不必要的内容。
如下面的例子:

// 在界面上显示用户输入
setInputValue(input);
// 在界面上呈现查询结果
setSearchQuery(input);
setInputValue会立即更新用户的输入到界面上,属于需要紧急更新的操作。setSearchQuery是根据用户输入,查询相应的内容,用户可以输入很多次,如果一直查询会可能会导致过多的js计算消耗在查询上面(甚至阻塞输入操作),而一般来说用户的期望值是「等待输入完成之后,查询并显示最终的结果」,因此这里的setSearchQuery可以看成是非紧急更新。
通过startTransition包裹setSearchQuery将其标记为非紧急更新:
setInputValue(input);
// 标记为非紧急更新
startTransition(() => {
React.setSearchQuery(input);
});
2.3 setTimeout的区别
就上面setSearchQuery的例子,使用setTimeout(或者debounce or throttle)也能达到相似的目的,那这个startTransition和setTimeout有啥区别?
一个重要区别是setTimeout是「延迟」执行,startTransition是立即执行的,传递给startTransition的函数是同步运行,但是其内部的所有更新都会标记为非紧急,React将在稍后处理更新时决定如何render这些updates,这意味着将会比setTimeout中的更新更早地被render。

相关文章:

  • springboot实验课程辅助管理系统毕业设计-附源码191113
  • Java面向对象(封装,继承,多态,接口)
  • 头门港大屏
  • pip更改为国内源
  • DBCO-PEG-carboxyl COOH-PEG-DBCO 二苯并环辛炔-聚乙二醇-羧酸 羧酸修饰PEG二苯并环辛炔
  • 【Java 语言】4、如何接收用户键盘输入
  • 猿创征文|我的 Java 成长之路
  • Docker01:概述与历史
  • 网站交换友情链接是否对SEO优化有帮助?
  • Vue.js核心技术解析与uni-app跨平台实战开发学习笔记 第10章 Vuex状态管理 10.1 Vuex基础应用
  • C++枚举
  • 动手学深度学习笔记-线性回归和softmax回归底层从零实现
  • 基于MATLAB的采样保持器的仿真
  • Qt之语言家的简单使用(一)(Qt翻译UI,Qt Linguist的使用,含源码+注释)
  • C++ STL --- vector类模拟实现
  • SegmentFault for Android 3.0 发布
  • 2017年终总结、随想
  • C学习-枚举(九)
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • flutter的key在widget list的作用以及必要性
  • Java应用性能调优
  • Linux快速复制或删除大量小文件
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • react 代码优化(一) ——事件处理
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 电商搜索引擎的架构设计和性能优化
  • 精彩代码 vue.js
  • 每天10道Java面试题,跟我走,offer有!
  • 前端学习笔记之观察者模式
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 听说你叫Java(二)–Servlet请求
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​LeetCode解法汇总518. 零钱兑换 II
  • # include “ “ 和 # include < >两者的区别
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • ###C语言程序设计-----C语言学习(6)#
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (11)MATLAB PCA+SVM 人脸识别
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (多级缓存)多级缓存
  • (过滤器)Filter和(监听器)listener
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (十六)Flask之蓝图
  • (四)图像的%2线性拉伸
  • (万字长文)Spring的核心知识尽揽其中
  • (转)ORM
  • (转)Sql Server 保留几位小数的两种做法
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .Net Core和.Net Standard直观理解
  • .NET Framework与.NET Framework SDK有什么不同?