学习React-11-useDeferredValue
useDeferredValue
useDeferredValue 是 React 18 引入的一个 Hook,用于延迟更新某些非关键渲染内容,以提升性能。它通过将低优先级的更新推迟到高优先级任务完成后执行,避免主线程阻塞,尤其适用于
输入框联想搜索
等场景。
核心功能
- 延迟渲染:接收一个状态值,返回一个延迟版本的值。React 会在高优先级更新完成后,再处理该值的更新。
- 优先级调度:与并发模式(Concurrent Mode)协同工作,确保用户交互(如输入)的流畅性。
基本用法
// query:实时响应用户输入的状态// deferredQuery:延迟更新的值,传递给耗时的子组件(如搜索结果列表)const deferredQuery = useDeferredValue(query);
适用场景
✅ 输入联想搜索:输入框内容实时更新,但搜索结果可稍后渲染。
✅ 大数据列表渲染:避免列表渲染阻塞用户交互。
✅ 非关键UI更新:如次要图表、统计数据的延迟加载。
useTransition 和 useDeferredValue 的区别
useTransition 是“我推迟我发起的更新”, useDeferredValue 是“我推迟别人传给我的值”
维度 | useTransition | useDeferredValue |
---|---|---|
控制对象 | 状态更新函数(setState) | 某个具体值(props / state) |
触发主体 | 当前组件主动发起更新 | 父组件传值,当前组件被动“延缓” |
返回值 | [isPending, startTransition] | deferredValue |
典型场景 | 路由切换、筛选项、搜索按钮点击 | 实时搜索输入框、高频变化的列表渲染 |
是否产生加载状态 | 有 isPending 布尔值 | 无内置加载状态,需自己对比 value !== deferredValue |
是否可取消/跳过 | 高优先级更新可中断低优先级 | 同左(都是 concurrent render) |
简单来说:
- 需要
点按钮
、选筛选项
、切路由
→ 用 useTransition - 需要
输入框实时反映
、列表慢点渲染
→ 用 useDeferredValue
小栗子-延迟搜索数据的更新
import React, { useState, useTransition, useDeferredValue } from 'react'
import { Input, List } from 'antd'
import mockjs from 'mockjs'// 定义列表项数据类型
interface ResultType {name: number // 名称address: string // 地址
}export function UseTransition() {const [val, setVal] = useState('')const [list] = useState<ResultType[]>(() => {return mockjs.mock({'list|10000': [{name: '@natural',address: '@county(true)'}]}).list})// val 时时状态, deferredQuery 延迟后的状态const deferredQuery = useDeferredValue(val)const isStale = deferredQuery !== val // 检查是否为延迟状态const findItem = () => {console.log(`${deferredQuery}---${val}`)return list.filter(item => item.name.toString().includes(deferredQuery))}return (<div><Input value={val} onChange={(e) => setVal(e.target.value)} /><List loading={isStale} renderItem={(item) => <List.Item><List.Item.Meta title={item.name} description={item.address} /></List.Item>} dataSource={findItem()}></List></div>)
}
效果如下:
注意:
useDeferredValue 并不同于防抖机制,它并不能设置延时时间。useDeferredValue的延时时间是根据设备性能来的。