学习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的延时时间是根据设备性能来的。

相关推荐
程序员黑豆9 小时前
鸿蒙应用开发:Flex 组件从入门到实战
前端·华为·harmonyos
大爱编程♡9 小时前
Vue3+TypeScript+element-plus的文章管理项目(配后端接口)-退出及文章管理页面
前端·javascript·typescript
先吃饱再说9 小时前
React 组件设计:从 Props 传递到组件封装
前端·react.js
独立开阀者_FwtCoder9 小时前
最近做了一个健身小程序:智形健身助手,健身的佬们来提点意见
前端·javascript·github
舒灿9 小时前
喵ing Tab 1.0.0 正式发布
前端·ai编程
我想我不够好。9 小时前
监控学习 7.23 1.5hour
学习
葡萄城技术团队9 小时前
当表格数据来自外部系统:SpreadJS 如何让异步公式一键刷新
前端
小徐_23339 小时前
Open Wot 1.0.5 发布:让 AI 接入 wot-ui,只需要两条命令
前端·uni-app·ai编程
Android研究员9 小时前
Android进阶之事件分发机制深度剖析
android·前端·面试
Csvn10 小时前
🛡️ 前端水印方案全解析——从「能被 F12 删掉」到「删不掉」的反破解实战
前端