useTransition和useDeferredValue

166 阅读2分钟

介绍

React v18开始,官方引入了并发模式(Concurrent Mode)和一些相关的Hooks,其中之一就是useTransition。开发者可以将某些状态更新标记为“可中断”的,从而允许React在必要时打断这些更新,先处理其他更为紧急的任务。我们把这种渲染效果称作“非阻塞UI”。

即允许在渲染未完成的情况下仍保持ui的响应性。


useTransition

用法

const [isPending, startTransition] = useTransition()
  • isPending:是一个布尔值,当过渡状态仍在进行中时,其值为true;否则为false
  • startTransition:是一个函数,当你希望启动一个新的过渡状态时调用它。

具体可以参考官网示例:react.docschina.org/reference/r…

原理

  • 并发模式下的状态更新分类: 在React的并发模式中,不是所有的状态更新都被视为等同的。React将更新分为不同的优先级类别,其中某些更新(如输入处理)被认为是更加紧急的,而其他更新(如从服务器获取数据)则可以中断或者延后更新。

  • 使用startTransition进行状态更新: 当你使用startTransition函数进行状态更新时,你实际上告诉 React:这个更新不是非常紧急的,如果有更重要的更新要处理,你可以中断或延后这个次要更新。

  • isPending的用途: isPending 为我们提供了一个标识,告诉我们是否有一个startTransition正在执行。我们可以根据isPending来设置过渡状态的样式。

本质上是将用startTransition包裹的组件渲染操作标记为低优先级,从而让给高优先级的渲染防止阻塞ui操作。


useDeferredValue

用法

const [newValue, setNewValue] = useState(value)
const [isPending, startTransition] = useTransition()

常用于input框,可以实时响应用户输入

与useTransition的关系

实际效果与useTransition类似

下面实现一个简单的模拟

const [newValue, setNewValue] = useState(value)
const [isPending, startTransition] = useTransition()

useEffect(() => { 
    startTransition(() => setNewValue(value))
}, [value, startTransition])

通过代码可以看到,二者的原理其实是相似的,react的源码也是使用了类似的方法

参考

juejin.cn/post/727858…

juejin.cn/post/708346…