R36第 1 / 1 课时未开始内容版本 1.0.0 · 核验于 2026-10-26

延迟更新与交互响应

延迟更新与交互响应 · 阅读后完成下方实验与检查题,再用「标记完成」记录进度。

学习目标

读完你能在「输入必须跟手、结果可以慢一点」的场景里使用 useDeferredValue 和 useTransition,说清这两个 API 的分工,并用快速输入验证:输入框始终即时响应,昂贵的结果晚一拍更新,界面不再被计算卡住。

问题场景

课程库搜索:输入框每敲一个字,都对两万多条记录做一遍过滤。键盘越敲越卡——因为每次按键都要等最贵的部分算完才肯更新界面,连输入框自己的回显都被拖累了。用户真正要的是一个优先级安排:字符出现在输入框里是高优先级,列表结果更新是低优先级。

核心解释

React 把更新分成紧急与非紧急两档,两个 API 分别覆盖两种写法。写法一:值在渲染中消费,用 useDeferredValue:

const deferredKeyword = useDeferredValue(keyword);
const result = useMemo(() => heavyFilter(deferredKeyword), [deferredKeyword]);
// 输入框绑定 keyword,立刻更新;列表绑定 deferredKeyword,允许晚一拍

写法二:更新在事件处理函数里发起,用 useTransition:

const [isPending, startTransition] = useTransition();
function onTabChange(next) {
  setKeyword(e.target.value);              // 紧急:输入反馈立刻渲染
  startTransition(() => setActive(next)); // 非紧急:切换大列表可以被插队
}

共同点:它们都不让计算变快,而是让贵的更新给紧急更新让路。输入帧永远优先渲染,结果帧慢一点,用户反而觉得更跟手。分工看视角:useDeferredValue 管「一个值被消费的时刻」,适合受控输入加派生计算;useTransition 管「一段更新的发起时机」,适合事件里切 tab、翻页这类成片的非紧急更新。

验证方式:页面同时显示「输入框的值」和「列表正在用的值」。快速连续输入时,开启延迟的两个值会短暂不一致——这正是延迟生效的直接证据;关闭延迟则每一拍都要等计算完成,输入明显发滞。

示例拆解

实验区是一个一万两千条记录的搜索页:

  • 「使用 useDeferredValue」开关:关 = 输入直接驱动列表;开 = 延迟值桥接;
  • 中间实时对比「输入框的值」与「列表正在用的值」,快速输入时能看到差拍提示;
  • 「切换到大库」按钮用 useTransition 包住:切换三万六千条数据期间按钮显示非紧急提示,期间仍可正常打字;
  • 验证:关闭延迟快速输入 5 个字符,感受卡顿;打开后再输一遍,对比手感与两个值的差拍。

动手任务

打开本课实验区:

  1. 关闭延迟开关,快速输入一串字符,记录卡顿感;打开开关重复一遍,对比并留意两个值的差拍。
  2. 把 useDeferredValue(keyword) 换成直接用 keyword(即删掉延迟一行),确认卡顿回归,再恢复。
  3. 连点「切换到大库」两次,观察 isPending 提示与最终落点:被打断的过渡更新不会留下中间结果,最终显示最后一次切换。

常见错误

  • 把 useDeferredValue 当防抖:防抖是少执行,延迟更新是错峰执行;它不减少计算量,只是不让计算阻塞输入帧。
  • 在延迟计算里做副作用:延迟渲染可能被中断重跑,副作用会执行多次;副作用应放在 Effect 或事件处理里。
  • 把紧急更新标成 transition:把输入框自己的 setKeyword 包进 startTransition,输入反馈反而变慢;紧急的永远是用户直接操作的即时反馈。
  • 期望它解决「单次计算太贵」:优先级重排不缩短单次耗时,配合上一课的缓存或后续的防抖请求才是完整方案。

检查与复盘

自查清单:

  • 能说出分工:值消费时机用 useDeferredValue,更新发起时机用 useTransition
  • 验证过:开延迟后快速输入,输入框回显与列表值出现差拍,且输入不卡
  • 知道 isPending 表示有非紧急更新在排队,不代表紧急更新被延迟

参考资料

动手实验
动手实验
预览
点击「运行」在隔离沙箱中预览
检查题共 2 题,提交后立即显示解析
答案由服务端判定;答错的题会自动进入复习计划。
Q1单选简单

关于 useTransition / startTransition 与 useDeferredValue,下列说法正确的是?

Q2单选中等

输入框 keyword 直接驱动一个 5000 行的过滤表格,打字明显卡顿。改用 const deferredKeyword = useDeferredValue(keyword) 后,表格改用 deferredKeyword 过滤。下列说法正确的是?

读完这一课了?

标记完成后,工作台会安排接下来的学习。

Command Palette

Search for a command to run...