目录
- 概述
- 基本用法
- 与防抖节流的区别
- 利用场景
- 区分过期内容
- 最佳实践
概述
什么是 useDeferredValue?
useDeferredValue 是 React 18 引入的新 Hook,用于耽误更新某个不那么紧张的部门。它接收一个值并返回该值的新副本,新副本会耽误更新。这种耽误是有益的,让告急更新(如用户输入)优先于不告急的更新(如渲染搜索结果列表)。
主要特点
- 主动处置惩罚耽误
- 与 Suspense 集成
- 不会像防抖和useTransition那样抛弃中间值
- 可以区分过期/最新内容
基本用法
1. 基本语法
- import { useDeferredValue } from 'react';
- function SearchResults() {
- const [query, setQuery] = useState('');
- const deferredQuery = useDeferredValue(query);
-
- return (
- <div>
- <input value={query} onChange={e => setQuery(e.target.value)} />
- <SlowList query={deferredQuery} /> {/* 使用延迟值进行渲染 */}
- </div>
- );
- }
复制代码 2. 区分过期内容示例
- function SearchResults() {
- const [query, setQuery] = useState('');
- const deferredQuery = useDeferredValue(query);
- const isStale = query !== deferredQuery; // 判断内容是否过时
-
- return (
- <div>
- <input value={query} onChange={e => setQuery(e.target.value)} />
- <div style={{
- opacity: isStale ? 0.8 : 1,
- transition: 'opacity 0.2s ease'
- }}>
- <SlowList query={deferredQuery} />
- </div>
- {isStale && <div>Loading new results...</div>}
- </div>
- );
- }
复制代码 与防抖节流的区别
1. 防抖 (Debounce)
- // 防抖示例
- function SearchWithDebounce() {
- const [query, setQuery] = useState('');
-
- const debouncedSearch = useCallback(
- debounce((value) => {
- // 执行搜索
- performSearch(value);
- }, 500),
- []
- );
-
- // 会丢弃中间值,只处理最后一次输入
- return (
- <input
- onChange={e => {
- setQuery(e.target.value);
- debouncedSearch(e.target.value);
- }}
- />
- );
- }
复制代码 2. 节流 (Throttle)
- // 节流示例
- function SearchWithThrottle() {
- const [query, setQuery] = useState('');
-
- const throttledSearch = useCallback(
- throttle((value) => {
- performSearch(value);
- }, 100),
- []
- );
-
- // 固定时间间隔执行,可能会延迟响应
- return (
- <input
- onChange={e => {
- setQuery(e.target.value);
- throttledSearch(e.target.value);
- }}
- />
- );
- }
复制代码 3. useDeferredValue
- // useDeferredValue 示例
- function SearchWithDeferred() {
- const [query, setQuery] = useState('');
- const deferredQuery = useDeferredValue(query);
-
- // React 会根据用户设备性能和当前 CPU 负载自动调整延迟
- // 不会丢弃任何值,而是以较低优先级处理它们
- return (
- <>
- <input onChange={e => setQuery(e.target.value)} />
- <SlowList query={deferredQuery} />
- </>
- );
- }
复制代码 利用场景
1. 大列表渲染
- function VirtualizedList({ items }) {
- const [filter, setFilter] = useState('');
- const deferredFilter = useDeferredValue(filter);
- const isStale = filter !== deferredFilter;
-
- const filteredItems = useMemo(
- () => items.filter(item => item.includes(deferredFilter)),
- [deferredFilter, items]
- );
-
- return (
- <div>
- <input value={filter} onChange={e => setFilter(e.target.value)} />
- <div style={{ opacity: isStale ? 0.8 : 1 }}>
- {filteredItems.map(item => (
- <ListItem key={item} item={item} />
- ))}
- </div>
- </div>
- );
- }
复制代码 2. 实时预览
- function MarkdownEditor() {
- const [text, setText] = useState('');
- const deferredText = useDeferredValue(text);
- const isStale = text !== deferredText;
-
- return (
- <div className="editor">
- <textarea
- value={text}
- onChange={e => setText(e.target.value)}
- />
- <div className={`preview ${isStale ? 'stale' : ''}`}>
- <MarkdownPreview text={deferredText} />
- </div>
- </div>
- );
- }
复制代码 最佳实践
- function SlowList({ text }) {
- const deferredText = useDeferredValue(text);
- const isStale = text !== deferredText;
-
- // 使用 useMemo 避免不必要的重新计算
- const items = useMemo(
- () => computeExpensiveList(deferredText),
- [deferredText]
- );
-
- return (
- <div style={{ opacity: isStale ? 0.8 : 1 }}>
- {items.map(item => (
- <ListItem key={item.id} item={item} />
- ))}
- </div>
- );
- }
复制代码- function SearchResults({ query }) {
- const deferredQuery = useDeferredValue(query);
- const isStale = query !== deferredQuery;
-
- return (
- <div>
- {isStale && (
- <div className="stale-indicator">
- Showing results for "{deferredQuery}"
- <br />
- Updating results for "{query}"...
- </div>
- )}
- <ResultsList query={deferredQuery} />
- </div>
- );
- }
复制代码 总结
- useDeferredValue vs 防抖/节流:
- useDeferredValue 不会抛弃更新
- 主动顺应用户设备性能
- 与 React 并发特性集成
- 提供过期状态标识
- 适用场景:
- 大数据列表渲染
- 实时预览功能
- 复杂图表更新
- 搜索发起
- 最佳实践:
- 配合 useMemo 利用
- 提供加载状态反馈
- 公道处置惩罚过期内容
- 注意性能优化
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |