网站上线如何做公司名字,wordpress walker,关键词排名优化外包,服务号微商城怎么开通文章目录 前言Automatic BatchingTransitionsSuspenseNew Hooks后言 前言 hello world欢迎来到前端的新世界 #x1f61c;当前文章系列专栏#xff1a;react.js #x1f431;#x1f453;博主在前端领域还有很多知识和技术需要掌握#xff0c;正在不断努力填补技术短板。… 文章目录 前言Automatic BatchingTransitionsSuspenseNew Hooks后言 前言 hello world欢迎来到前端的新世界 当前文章系列专栏react.js 博主在前端领域还有很多知识和技术需要掌握正在不断努力填补技术短板。(如果出现错误感谢大家指出) 感谢大家支持您的观看就是作者创作的动力 Automatic Batching
早在 React 18 之前React 就已经可以对 state 更新进行批处理了
function App() {const [count, setCount] useState(0);const [flag, setFlag] useState(false);function handleClick() {setCount((c) c 1); // Does not re-render yetsetFlag((f) !f); // Does not re-render yet// React will only re-render once at the end (thats batching!)}return (divdiv{count}/divbutton onClick{handleClick}Next/button/div);
}上面这个例子中用户点击按钮时会产生两次 state 的更新按理来说每次 state 更新都会导致一次 re-render。但是这两次更新完全可以合成一次从而减少无谓的 re-render 带来的性能损失。
这种批处理只限于 React 原生事件内部的更新。
在 React 18 中批处理支持处理的操作范围扩大了PromisesetTimeoutnative event handlers 等这些非 React 原生的事件内部的更新也会得到合并
// Before: only React events were batched.setTimeout(() {setCount((c) c 1);setFlag((f) !f);// React will render twice, once for each state update (no batching)
}, 1000);// After: updates inside of timeouts, promises,// native event handlers or any other event are batched.setTimeout(() {setCount((c) c 1);setFlag((f) !f);// React will only re-render once at the end (thats batching!)
}, 1000);Transitions
Transitions 是 React 中一个用于区分高优更新和非高优更新的新概念。 高优的更新/渲染包括鼠标点击、打字等对实时交互性要求很高的更新场景卡顿时会影响用户的交互行为使用户明显感到整个页面卡顿。 非高优的更新/渲染普通的 UI 更新不与用户的交互相关一些对更新实时性要求没那么高的场景。
这里有一个 demo上方是一个滑动条用于控制下方树的倾角最顶上的扇区展示了当前的掉帧情况当用户拉动滚动条时下方的树的每一个节点都会重新渲染这会带来明显的卡顿不仅是下方树的渲染卡顿上方的滚动条也会无法实时跟着用户的交互移动这会给用户带来明显的卡顿感。
类似场景下常见的做法应该是 debounce 或 throttle React 18 为我们提供了原生的方式来解决这个问题使用 starTransition 和 useTransition。
starTransition用于标记非紧急的更新用 starTransition 包裹起来就是告诉 React这部分代码渲染的优先级不高可以优先处理其它更重要的渲染。用法如下
import { startTransition } from react;// Urgent
setSliderValue(input);// Mark any state updates inside as transitions
startTransition(() {// Transition: Show the results, non-urgentsetGraphValue(input);
});useTransition除了能提供 startTransition 以外还能提供一个变量来跟踪当前渲染的执行状态
import { useTransition } from react;const [isPending, startTransition] useTransition();return isPending Spinner /;在勾选了 Use startTransition 后 滑动条的更新渲染不会再被树的渲染阻塞了尽管树叶的渲染仍然需要较多的时间但是用户使用起来不再有之前那么卡顿了。
Suspense
Suspense 是 React 提供的用于声明 UI 加载状态的 API
Suspense fallback{Loading /}ComponentThatSuspends /Sibling /
/Suspense上面这串代码里组件 ComponentThatSuspends 在请求处理数据过程中React 会在它的位置上展示 Loading 组件。
React 16 和 17 中也已经有 Suspense 了但是它不是完全体有许多功能仍未就绪。在 React 团队的计划中Suspense 的完全体是基于 Concurrent React 的所以在 React 18Suspense 相较之前有了一些变化。
ComponentThatSuspends 的兄弟组件会被中断 还是上面那个例子
Suspense fallback{Loading /}ComponentThatSuspends /Sibling /
/SuspenseLegacy Suspense 中同级兄弟组件会立即挂载mounted到 DOM相关的 effects 和生命周期会被触发最后会隐藏这个组件。具体可以查看 代码示例。 Concurrent Suspense 中同级兄弟组件并不会从 DOM 上卸载相关的 effects 和生命周期会在 ComponentThatSuspends 处理完成时触发
Suspense 边界之外的 ref 另一个差异是父级 ref 传入的时间
Suspense fallback{Loading /}ComponentThatSuspends /Sibling /
/Suspense- 在 Legacy Suspense 中在渲染之初 refPassedFromParent.current 立即指向 DOM 节点此时 ComponentThatSuspends 还未处理完成。
在 Concurrent Suspense 中在 ComponentThatSuspends 完成处理、Suspense 边界解除锁定之前 refPassedFromParent.current 一直为 null。
也就是说在父级代码中访问此类 ref 都需要关注当前 ref 是否已经指向相应的节点。 Suspense for SSR React 18 之前的 SSR 客户端必须一次性的等待 HTML 数据加载到服务器上并且等待所有 JavaScript 加载完毕之后再开始 hydration 等待所有组件 hydration 后才能进行交互。即整个过程需要完成从获取数据服务器→ 渲染到 HTML服务器→ 加载代码客户端→ 水合物客户端这一套流程。这样的 SSR 并不能使我们的完全可交互变快只是提高了用户的感知静态页面内容的速度。 React 18 的 Suspense 服务器不需要等待被 Suspense 包裹组件是否加载到完毕即可发送 HTML而代替 Suspense 包裹的组件是 fallback 中的内容一般是一个占位符spinner以最小内联 hydration 的过程是逐步的不需要等待所有的 js 加载完毕再开始 hydration避免了页面的卡顿。 React 会提前监听页面上交互事件如鼠标的点击对发生交互的区域优先进行 hydration。
New Hooks useTransition见上 useDeferredValue startTransition 可以用来标记低优先的 state 更新而useDeferredValue 可以用来标记低优先的变量。 下方代码的具体效果是当 input 的值改变时返回的 graphValue 并不会立即改变会首先返回上一次的 input 值如果当前不存在更紧急的更新才会变成最新的 input因此可以通过 graphValue 是否改变来进行一些低优先级的更新。可以在渲染比较耗时的情况下把优先级滞后在多数情况不会存在不必要的延迟。在较快的机器上滞后会更少或者根本不存在在较慢的机器上会变得更明显。但不论哪种情况应用都会保持可响应。
import { useDeferredValue } from react;const Comp (input) {const graphValue useDeferredValue(input); // ...updating depends on graphValue
};不常用的 hooks 以下的新 hook 主要用于解决 SSR 相关的问题或者是为第三方库的开发设计的对于普通 React 应用开发者来说几乎用不到 useId 用于解决 SSR 时客户端与服务端难以生成统一的 ID 的问题。 useSyncExternalStore 是一个为第三方库编写提供的新 hook主要用于支持 React 18 在 concurrent rendering 下与第三方 store 的数据同步问题。 useInsertionEffect 主要用于提高第三方 CSS in JS 库渲染过程中样式注入的性能。
后言 创作不易要是本文章对广大读者有那么一点点帮助 不妨三连支持一下您的鼓励就是博主创作的动力