认识
一、认识
useTransition
用于在 createRoot
开启的并发特性模式下, 开启并发渲染。主要解决浏览器执行大量渲染工作问题时的卡顿问题。useTransition
返回一个数组, 第一个元素为 isPending
, 表示当处于过渡状态的标志; 第二个是 startTransition
, 一个方法, 里面的更新任务都会被标记成 过渡更新任务,过渡更新任务在渲染并发场景下,会被降级更新优先级,中断更新, 所以它不会让页面卡顿,React
让这些任务,在浏览器空闲时间执行。
二、语法
import { useTransition } from 'react';
function TabContainer() {
const [value, setValue] = useState(0);
const [isPending, startTransition] = useTransition();
const handleClick = ()=>{
startTransition(()=>{
setValue(1);
});
}
return <div>
{ isPending && <span>isTransition</span>}
<button onClick={handleClick}></button>
<div>{ value }</div>
</div>
}
-
isPending
: 告诉你是否存在待处理的transition
。 -
startTransition
: 可以使用此方法将状态更新标记为transition
三、问题
3.1 useTransition 实现原理?
3.2 useTransition vs useDeferredValue?
useDeferredValue
本质上和内部实现与 useTransition
一样都是标记成了过渡更新任务。但是, useTransition
是把 startTransition
内部的更新任务变成了过渡任务 transition
,而 useDeferredValue
是把原值通过过渡任务得到新的值,这个值作为延时状态。 一个是处理一段逻辑,另一个是生产一个新的状态。useDeferredValue
还有一个不同点就是这个任务,本质上在 useEffect
内部执行,而 useEffect
内部逻辑是异步执行的 ,所以它一定程度上更滞后于 useTransition
。 useDeferredValue = useEffect + transition
3.3 useTransition 解决了什么问题? 可以用节流代替吗?
useTransition
用于在 createRoot
开启的并发特性模式下, 开启并发渲染。主要解决浏览器执行大量渲染工作问题时的卡顿问题。useTransition
返回一个数组, 第一个元素为 isPending
, 表示当处于过渡状态的标志; 第二个是 startTransition
, 一个方法, 里面的更新任务都会被标记成 过渡更新任务,过渡更新任务在渲染并发场景下,会被降级更新优先级,中断更新, 所以它不会让页面卡顿,React
让这些任务,在浏览器空闲时间执行。
节流防抖 也可以解决大量渲染工作同时渲染卡顿的问题, 但是节流防抖导致更新任务的执行时间变长了, 视图改变的时间也会延长。所以 startTransition
与 节流防抖 的本质区别是: 一方面,节流防抖 本质上也是 setTimeout
,只不过控制了执行的频率,那么通过打印的内容就能发现,原理就是让 render
次数减少了。而 transitions
和它相比,并没有减少渲染的次数。另一方面,节流和防抖需要有效掌握 Delay Time
延时时间,如果时间过长,那么给人一种渲染滞后的感觉,如果时间过短,那么就类似于 setTimeout(fn,0)
还会造成前面的问题。而 startTransition
就不需要考虑这么多。
3.4 useTransition 解决了什么问题? 可以用 setTimeout 替代吗?
useTransition
用于在 createRoot
开启的并发特性模式下, 开启并发渲染。主要解决浏览器执行大量渲染工作问题时的卡顿问题。useTransition
返回一个数组, 第一个元素为 isPending
, 表示当处于过渡状态的标志; 第二个是 startTransition
, 一个方法, 里面的更新任务都会被标记成 过渡更新任务,过渡更新任务在渲染并发场景下,会被降级更新优先级,中断更新, 所以它不会让页面卡顿,React
让这些任务,在浏览器空闲时间执行。
setTimeout
同样可以解决大量渲染工作同时渲染卡顿的问题, startTransition
相比 setTimeout
的优势和异同是: 一方面, startTransition
的处理逻辑和 setTimeout
有一个很重要的区别,setTimeout
是异步延时执行,而 startTransition
的回调函数是同步执行的。在 startTransition
之中任何更新,都会标记上 transition
,React
将在更新的时候,判断这个标记来决定是否完成此次更新。所以 Transition
可以理解成比 setTimeout
更早的更新。但是同时要保证 ui
的正常响应,在性能好的设备上,transition
两次更新的延迟会很小,但是在慢的设备上,延时会很大,但是不会影响 UI
的响应。另一方面,对于渲染并发的场景下,setTimeout
仍然会使页面卡顿。因为超时后,还会执行 setTimeout
的任务,它们与用户交互同样属于宏任务,所以仍然会阻止页面的交互。那么 transition
就不同了,在 conCurrent mode
下,startTransition
是可以中断渲染的 ,所以它不会让页面卡顿,React
让这些任务,在浏览器空闲时间执行