React 的 useTransition 和 useDeferredValue 有什么区别?它们等于防抖吗?
下面是一段教学用的模拟面试。
🧑💻 面试官:搜索框打字很卡,useTransition 能解决吗?
🙋♂️ 我:可以让昂贵的结果更新成为非紧急更新,先响应输入。
🧑💻 面试官:那输入框的 value 更新也放进去?
🙋♂️ 我:不行,受控输入需要及时更新,不能把这一步做成 Transition。
🧑💻 面试官:如果搜索词是父组件传来的,拿不到 setter,用什么?加了以后接口请求会自动减少吗?
这里安排的是「谁先更新画面」,不是把请求防抖、计算卸载和渲染调度合成一个功能。
面试速答(60 秒版)
useTransition 用来把由当前代码发起的某些状态更新标记为非紧急,并提供 isPending 表示过渡状态。输入等紧急更新可以打断这些渲染工作。
useDeferredValue 适合已经拿到一个值,希望昂贵的下游界面暂时使用旧值。它不要求你掌握原来的 setter,适合父组件传来的搜索词。
它们不等于防抖,没有固定等待多少毫秒的规则,也不会自动减少接口请求或把长计算放到后台线程。项目里要让输入及时变化,再延后结果界面的工作;如果瓶颈是大量同步计算或请求太多,还得分别优化计算和请求策略。

图:输入要快,列表可以稍后更新。
知识点详解:输入很轻,为什么结果列表把它拖慢了?
一个输入动作,引出了两种工作
假设页面显示搜索框和很复杂的结果列表。输入一个字,搜索框只需要显示新的文本;列表却可能重新生成大量组件。
两件事都需要发生,但紧急程度不同。用户正在打字,首先希望按键立刻反映在输入框里。结果晚一点更新,通常比连输入都卡住更容易接受。
有更新入口,用 Transition 标记工作
代码既能更新输入状态,也能更新结果条件时,可以把输入更新留在普通路径,把结果条件的更新标记为 Transition。useTransition 文档说明了可中断更新以及受控输入限制。
这里的回调不是一个延迟执行的后台任务。把耗时循环写在 startTransition 回调里,循环仍会在当前执行中花时间;React 主要调整相关状态更新引起的渲染工作。
只有传入的值,用 Deferred Value
假设列表组件只收到父组件的 query,没有权力改变父组件状态。它可以得到一个 deferredQuery,让昂贵的子树暂时显示旧结果,再在后台渲染新结果。useDeferredValue 文档说明了这种暂时落后的显示关系。
但如果列表在同一次紧急渲染里仍做了同样的重工作,延后一个变量就不一定有收益。组件边界、缓存与实际读取哪个值,都要一起检查。
本题讨论公共 API 与调度边界,流程比长代码更有用。Python 没有同一 React 渲染机制,不提供伪对应版本。

图:有更新入口,还是只有一个值?。
结果落后了,要不要告诉用户?
需要根据功能设计。可以比较 query 与 deferredQuery,适当显示「正在更新」或者降低旧结果的视觉权重,让用户知道它还不是最新搜索词对应的结果。
不要在落后结果里显示成已经完成的新答案,更不要让用户依据旧结果执行高风险操作。界面调度可以延迟展示,业务正确性不能跟着模糊。
它们为什么不等于防抖?
防抖按时间规则减少触发,例如停输入一段时间才请求。Deferred Value 没有固定延迟;设备处理得快,就可能很快跟上,处理得慢,则先保留旧显示。
因此,两种方案可以配合。减少网络请求用请求策略,维持输入流畅用渲染调度。验证时分别统计输入响应、渲染耗时、请求次数;只看到 pending 图标,并不能证明问题解决了。
面试官继续追问
CPU 计算很重,加 Transition 就会搬到 Worker 吗?
不会。需要把独立计算移到 Worker,或减少计算本身;一次不能被 React 拆开的同步函数仍会阻塞。
Transition 里的旧请求后返回,能保证不覆盖新结果吗?
不能把它当成通用的请求顺序保护。普通数据请求仍需要处理取消、结果归属与过期响应;特定框架 Action 的保证也要按版本核对。
哪个一定更快?
没有这种固定比较。看你控制的是更新动作还是已有值,并在实际组件边界上测收益。
面试速记卡
- useTransition:标记自己发起的非紧急更新。
- useDeferredValue:让下游暂用一个值的旧版本。
- 输入:受控文本更新保持及时,不做 Transition。
- 防抖:按时间减少触发,与渲染优先级不同。
- 边界:不自动减请求、不自动开线程、不保证响应顺序。
公司面试真题
这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。
浏览公司面试真题 →