React 中hooks之useDeferredValue用法总结

打印 上一主题 下一主题

主题 1016|帖子 1016|积分 3048

目录


  • 概述
  • 基本用法
  • 与防抖节流的区别
  • 利用场景
  • 区分过期内容
  • 最佳实践
概述

什么是 useDeferredValue?

useDeferredValue 是 React 18 引入的新 Hook,用于耽误更新某个不那么紧张的部门。它接收一个值并返回该值的新副本,新副本会耽误更新。这种耽误是有益的,让告急更新(如用户输入)优先于不告急的更新(如渲染搜索结果列表)。
主要特点



  • 主动处置惩罚耽误
  • 与 Suspense 集成
  • 不会像防抖和useTransition那样抛弃中间值
  • 可以区分过期/最新内容
基本用法

1. 基本语法

  1. import { useDeferredValue } from 'react';
  2. function SearchResults() {
  3.   const [query, setQuery] = useState('');
  4.   const deferredQuery = useDeferredValue(query);
  5.   
  6.   return (
  7.     <div>
  8.       <input value={query} onChange={e => setQuery(e.target.value)} />
  9.       <SlowList query={deferredQuery} /> {/* 使用延迟值进行渲染 */}
  10.     </div>
  11.   );
  12. }
复制代码
2. 区分过期内容示例

  1. function SearchResults() {
  2.   const [query, setQuery] = useState('');
  3.   const deferredQuery = useDeferredValue(query);
  4.   const isStale = query !== deferredQuery; // 判断内容是否过时
  5.   
  6.   return (
  7.     <div>
  8.       <input value={query} onChange={e => setQuery(e.target.value)} />
  9.       <div style={{
  10.         opacity: isStale ? 0.8 : 1,
  11.         transition: 'opacity 0.2s ease'
  12.       }}>
  13.         <SlowList query={deferredQuery} />
  14.       </div>
  15.       {isStale && <div>Loading new results...</div>}
  16.     </div>
  17.   );
  18. }
复制代码
与防抖节流的区别

1. 防抖 (Debounce)

  1. // 防抖示例
  2. function SearchWithDebounce() {
  3.   const [query, setQuery] = useState('');
  4.   
  5.   const debouncedSearch = useCallback(
  6.     debounce((value) => {
  7.       // 执行搜索
  8.       performSearch(value);
  9.     }, 500),
  10.     []
  11.   );
  12.   
  13.   // 会丢弃中间值,只处理最后一次输入
  14.   return (
  15.     <input
  16.       onChange={e => {
  17.         setQuery(e.target.value);
  18.         debouncedSearch(e.target.value);
  19.       }}
  20.     />
  21.   );
  22. }
复制代码
2. 节流 (Throttle)

  1. // 节流示例
  2. function SearchWithThrottle() {
  3.   const [query, setQuery] = useState('');
  4.   
  5.   const throttledSearch = useCallback(
  6.     throttle((value) => {
  7.       performSearch(value);
  8.     }, 100),
  9.     []
  10.   );
  11.   
  12.   // 固定时间间隔执行,可能会延迟响应
  13.   return (
  14.     <input
  15.       onChange={e => {
  16.         setQuery(e.target.value);
  17.         throttledSearch(e.target.value);
  18.       }}
  19.     />
  20.   );
  21. }
复制代码
3. useDeferredValue

  1. // useDeferredValue 示例
  2. function SearchWithDeferred() {
  3.   const [query, setQuery] = useState('');
  4.   const deferredQuery = useDeferredValue(query);
  5.   
  6.   // React 会根据用户设备性能和当前 CPU 负载自动调整延迟
  7.   // 不会丢弃任何值,而是以较低优先级处理它们
  8.   return (
  9.     <>
  10.       <input onChange={e => setQuery(e.target.value)} />
  11.       <SlowList query={deferredQuery} />
  12.     </>
  13.   );
  14. }
复制代码
利用场景

1. 大列表渲染

  1. function VirtualizedList({ items }) {
  2.   const [filter, setFilter] = useState('');
  3.   const deferredFilter = useDeferredValue(filter);
  4.   const isStale = filter !== deferredFilter;
  5.   
  6.   const filteredItems = useMemo(
  7.     () => items.filter(item => item.includes(deferredFilter)),
  8.     [deferredFilter, items]
  9.   );
  10.   
  11.   return (
  12.     <div>
  13.       <input value={filter} onChange={e => setFilter(e.target.value)} />
  14.       <div style={{ opacity: isStale ? 0.8 : 1 }}>
  15.         {filteredItems.map(item => (
  16.           <ListItem key={item} item={item} />
  17.         ))}
  18.       </div>
  19.     </div>
  20.   );
  21. }
复制代码
2. 实时预览

  1. function MarkdownEditor() {
  2.   const [text, setText] = useState('');
  3.   const deferredText = useDeferredValue(text);
  4.   const isStale = text !== deferredText;
  5.   
  6.   return (
  7.     <div className="editor">
  8.       <textarea
  9.         value={text}
  10.         onChange={e => setText(e.target.value)}
  11.       />
  12.       <div className={`preview ${isStale ? 'stale' : ''}`}>
  13.         <MarkdownPreview text={deferredText} />
  14.       </div>
  15.     </div>
  16.   );
  17. }
复制代码
最佳实践


  • 公道利用 useMemo
  1. function SlowList({ text }) {
  2.   const deferredText = useDeferredValue(text);
  3.   const isStale = text !== deferredText;
  4.   
  5.   // 使用 useMemo 避免不必要的重新计算
  6.   const items = useMemo(
  7.     () => computeExpensiveList(deferredText),
  8.     [deferredText]
  9.   );
  10.   
  11.   return (
  12.     <div style={{ opacity: isStale ? 0.8 : 1 }}>
  13.       {items.map(item => (
  14.         <ListItem key={item.id} item={item} />
  15.       ))}
  16.     </div>
  17.   );
  18. }
复制代码

  • 优雅降级处置惩罚
  1. function SearchResults({ query }) {
  2.   const deferredQuery = useDeferredValue(query);
  3.   const isStale = query !== deferredQuery;
  4.   
  5.   return (
  6.     <div>
  7.       {isStale && (
  8.         <div className="stale-indicator">
  9.           Showing results for "{deferredQuery}"
  10.           <br />
  11.           Updating results for "{query}"...
  12.         </div>
  13.       )}
  14.       <ResultsList query={deferredQuery} />
  15.     </div>
  16.   );
  17. }
复制代码
总结


  • useDeferredValue vs 防抖/节流:

    • useDeferredValue 不会抛弃更新
    • 主动顺应用户设备性能
    • 与 React 并发特性集成
    • 提供过期状态标识

  • 适用场景:

    • 大数据列表渲染
    • 实时预览功能
    • 复杂图表更新
    • 搜索发起

  • 最佳实践:

    • 配合 useMemo 利用
    • 提供加载状态反馈
    • 公道处置惩罚过期内容
    • 注意性能优化



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

盛世宏图

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表