--- title: 使用 useDeferredValue 处理昂贵的派生渲染 impact: MEDIUM impactDescription: 在繁重计算期间保持输入响应 tags: rerender, useDeferredValue, optimization, concurrent --- ## 使用 useDeferredValue 处理昂贵的派生渲染 当用户输入触发昂贵的计算或渲染时,使用 `useDeferredValue` 来保持输入响应。被延后的值会滞后,让 React 优先处理输入更新,并在空闲时再渲染昂贵的结果。 **错误做法(过滤时输入感觉卡顿):** ```tsx function Search({ items }: { items: Item[] }) { const [query, setQuery] = useState('') const filtered = items.filter(item => fuzzyMatch(item, query)) return ( <> setQuery(e.target.value)} /> ) } ``` **正确做法(输入保持流畅,结果就绪后渲染):** ```tsx function Search({ items }: { items: Item[] }) { const [query, setQuery] = useState('') const deferredQuery = useDeferredValue(query) const filtered = useMemo( () => items.filter(item => fuzzyMatch(item, deferredQuery)), [items, deferredQuery] ) const isStale = query !== deferredQuery return ( <> setQuery(e.target.value)} />
) } ``` **适用场景:** - 过滤/搜索大型列表 - 响应输入变化的昂贵可视化(图表、图形) - 任何会导致明显渲染延迟的派生状态 **注意:** 将昂贵的计算用 `useMemo` 包裹,并把被延后的值作为依赖项,否则它仍然会在每次渲染时执行。 参考文档:[React useDeferredValue](https://react.dev/reference/react/useDeferredValue)