useTransition 和 useDeferredValue 有什么用?区别?
一、是什么
useTransition 和 useDeferredValue 是 React 18 引入的两个并发特性 Hook,它们的核心目的相同:将某些更新标记为低优先级,从而保证高优先级更新(如用户输入)的流畅响应。
两者的根本区别在于作用对象不同:
useTransition:将一个状态更新操作标记为非紧急useDeferredValue:将一个已有的值延迟更新
二、useTransition
2.1 基本用法
useTransition 返回一个数组:
isPending:布尔值,表示 transition 是否正在等待(可用于显示加载指示)startTransition:函数,将其内部的状态更新标记为 transition(低优先级)
2.2 搜索过滤场景
这是 useTransition 最典型的应用场景——输入框保持流畅,列表渲染延迟更新:
2.3 与 Suspense 配合
startTransition 与 Suspense 有特殊的交互:在 transition 期间触发的 Suspense 不会立即显示 fallback,而是保持显示旧内容:
三、useDeferredValue
3.1 基本用法
useDeferredValue 接收一个值,返回该值的"延迟版本"。当传入的值变化时:
- React 先用旧值完成一次渲染(保证立即响应)
- 然后在后台用新值重新渲染(低优先级,可被中断)
- 新值渲染完成后,屏幕更新为新结果
3.2 完整的搜索示例
3.3 延迟渲染子树
useDeferredValue 的一个强大模式是延迟整个组件子树的渲染:
注意:useDeferredValue 需要配合 memo 或 useMemo 才能真正跳过不必要的渲染。如果子组件没有 memo,每次父组件渲染都会导致子组件重新渲染,deferred value 就失去了意义。
四、两者的核心区别
4.1 控制权归属
4.2 对比表
4.3 选择指南
五、进阶用法
5.1 startTransition(非 Hook 版本)
React 还导出了模块级的 startTransition 函数,可在组件外使用,但不提供 isPending:
5.2 React 19 扩展
startTransition支持异步函数(Actions),可在 transition 中执行async/awaituseDeferredValue增加了initialValue参数:useDeferredValue(query, '')
5.3 性能优化要点
memo包裹耗时组件,避免不必要的渲染useMemo缓存计算结果,确保 deferred/transition 值未变时不重新计算- 将输入状态和搜索状态分离,输入框始终即时响应
六、总结
useTransition 和 useDeferredValue 是 React 并发渲染的核心消费 API。它们不会让渲染本身变快,而是让 React 学会"先做重要的事"——确保用户感知到的界面始终保持响应。选择哪一个取决于你是否控制状态更新的源头:控制源头用 useTransition,只消费值用 useDeferredValue。