都是基于react18的transition过渡任务产生,详情见startTransition文章
useTranstion
将函数中的内容过渡,类比useCallback
const [ isPending , startTransition ] =useTransition()
isPending:过度任务状态,true代表过渡中,false过渡结束
startTransition:执行的过渡任务
startTransition(()=>{
...
})
useDeferredValue
过渡单个状态值,让状态滞后变化,类比useMemo
const pendingValue = useDeferredValue(value)
useTranstion和useDeferredValue异同:
相同点:
useDeferredValue本质上和内部实现与useTransition一样都是标记成了过渡更新任务。
不同点:
useDeferredValue本质上在useEffect内部执行,而useEffect内部逻辑是异步执行的,所以它一定程度上更滞后于useTransition
startTransition的回调函数是同步执行的。
在startTransition之中任何更新,都会标记上transition,React将在更新的时候,判断这个标记来决定是否完成此次更新。
所以Transition可以理解成比setTimeout更早的更新。
但是同时要保证ui的正常响应,在性能好的设备上,transition两次更新的延迟会很小,但是在慢的设备上,延时会很大,但是不会影响UI的响应。
代码示例:
useTranstion:
export default function App(){
const [ value ,setInputValue ] = React.useState('')
const [ query ,setSearchQuery ] = React.useState('')
const [ isPending , startTransition ] = React.useTransition()
const handleChange = (e) => {
setInputValue(e.target.value)
startTransition(()=>{
setSearchQuery(e.target.value)
})
}
return <div>
{
isPending && <span>isTransiton</span>}
<input onChange={
handleChange}
placeholder="输入搜索内容"
value={
value}
/>
<NewList query={
query} />
</div>
}
useDeferredValue:
export default function App(){
const [ value ,setInputValue ] = React.useState('')
const query = React.useDeferredValue(value)
const handleChange = (e) => {
setInputValue(e.target.value)
}
return <div>
<button>useDeferredValue</button>
<input onChange={
handleChange}
placeholder="输入搜索内容"
value={
value}
/>
<NewList query={
query} />
</div>
}