0Pricing
React Academy · 课时

使用 useDeferredValue 实现输入防抖

延迟界面中缓慢部分的重新渲染,同时保持输入操作灵敏。

使用 useDeferredValue 实现输入防抖 是 CoddyKit 上的免费 React Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。

欢迎

在本课中,您将使用 useDeferredValue 延迟界面中开销较大部分的重新渲染,同时让受控输入保持灵敏和响应迅速。

什么是 useDeferredValue

useDeferredValue 接收一个值并返回它的延迟版本。在紧急渲染期间,延迟值会落后于当前值,使 React 能够分两步更新界面:输入快速更新,开销较大的输出延后更新。
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
// query updates immediately on keystroke
// deferredQuery updates when React has capacity

应用于开销较大的组件

将延迟值而不是实时值传给开销较大的组件。只有在 deferredQuery 发生变化时,该组件才会重新渲染;快速输入时,deferredQuery 会落后于输入。
function App() {
  const [q, setQ] = useState('');
  const dq = useDeferredValue(q);
  return (
    <>
      <input value={q} onChange={e => setQ(e.target.value)} />
      <HeavyList query={dq} /> {/* renders with deferred value */}
    </>
  );
}

显示内容过时指示器

比较实时值和延迟值。当两者不同时,内容就是过时的,您可以通过降低不透明度将其调暗,或显示加载指示器。
const isStale = q !== dq;
<div style={{ opacity: isStale ? 0.5 : 1 }}>
  <HeavyList query={dq} />
</div>

useDeferredValue 与防抖的比较

基于 setTimeout 的防抖总会引入固定延迟(例如 300ms),即使在速度很快的设备上也是如此。useDeferredValue 会自适应:在快速设备上立即渲染,在慢速设备上延迟渲染以避免卡顿。

useDeferredValue 与 useTransition 的比较

当您 OWN 状态设置器(可以包裹 setState)时,请使用 useTransition。当您从属性或上下文中接收值且无法控制其更新时间时,请使用 useDeferredValue。
// You own the state: use useTransition
startTransition(() => setTab(newTab));

// You receive the value: use useDeferredValue
const deferredProp = useDeferredValue(props.searchQuery);

与 React.memo 结合使用

要让 useDeferredValue 有效跳过重新渲染,开销较大的组件必须包裹在 React.memo 中。否则,无论延迟值是否变化,只要父组件重新渲染,该组件就会重新渲染。
const HeavyList = React.memo(function({ query }) {
  // expensive rendering
  return <ul>{data.filter(q => ...).map(...)}</ul>;
});

首次渲染时的延迟值

首次渲染时,延迟值等于当前值,不存在延迟。只有在重新渲染期间当前值和延迟值不同时,延迟才会生效。

多个延迟值

您可以多次调用 useDeferredValue,分别用于界面中不同的开销较大部分,每个值都会独立延迟。
const deferredA = useDeferredValue(valueA);
const deferredB = useDeferredValue(valueB);

限制

useDeferredValue 不会让渲染速度更快,只会延迟渲染。如果开销较大的渲染需要 500ms,界面仍然会卡顿。对于真正大型的列表,请结合使用虚拟化(react-virtual)。

快速检查

与普通值相比,useDeferredValue 在什么时候能带来好处?

回顾

useDeferredValue 返回某个值的滞后版本。请将它传给使用 React.memo 包裹的开销较大组件。当 deferredValue !== value 时,显示内容过时指示器。对于自适应性能,请优先使用它,而不是固定延迟的防抖。

下一课

下一课:**用于数据与代码边界的 Suspense**——您将把 Suspense 与延迟加载和数据库结合起来,以实现清晰的加载状态。

常见问题解答

「使用 useDeferredValue 实现输入防抖」课时是免费的吗?

是的 — 「使用 useDeferredValue 实现输入防抖」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。

「使用 useDeferredValue 实现输入防抖」这节课中我会学到什么?

延迟界面中缓慢部分的重新渲染,同时保持输入操作灵敏。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 React Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「使用 useDeferredValue 实现输入防抖」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 React Academy 课中编写并运行代码吗?

能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 竞态条件与 Effect 清理
  2. 使用 useTransition 实现非阻塞式界面更新
  3. 使用 useDeferredValue 实现输入防抖
  4. 使用 Suspense 划分数据与代码边界
← 返回 React Academy