学习React-11-useDeferredValue

useDeferredValue

useDeferredValue 是 React 18 引入的一个 Hook,用于延迟更新某些非关键渲染内容,以提升性能。它通过将低优先级的更新推迟到高优先级任务完成后执行,避免主线程阻塞,尤其适用于输入框联想搜索等场景。

核心功能
  • 延迟渲染:接收一个状态值,返回一个延迟版本的值。React 会在高优先级更新完成后,再处理该值的更新。
  • 优先级调度:与并发模式(Concurrent Mode)协同工作,确保用户交互(如输入)的流畅性。
基本用法
ts 复制代码
  // 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
小栗子-延迟搜索数据的更新
ts 复制代码
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的延时时间是根据设备性能来的。

相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
一隅论数智1 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
XiHongShi20161 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
爱吃苹果的日记本1 天前
离散数学第六课
学习·离散数学
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js