React第十四章(useDeferredValue)

useDeferredValue

useDeferredValue 用于延迟某些状态的更新,直到主渲染任务完成。这对于高频更新的内容(如输入框、滚动等)非常有用,可以让 UI 更加流畅,避免由于频繁更新而导致的性能问题。

关联问题:useTransition 和 useDeferredValue 的区别

useTransitionuseDeferredValue 都涉及延迟更新,但它们关注的重点和用途略有不同:

  • useTransition主要关注点是状态的过渡。它允许开发者控制某个更新的延迟更新,还提供了过渡标识,让开发者能够添加过渡反馈。
  • useDeferredValue主要关注点是单个值的延迟更新。它允许你把特定状态的更新标记为低优先级。

用法

ts 复制代码
const deferredValue = useDeferredValue(value)

参数

  • value: 延迟更新的值(支持任意类型)

返回值

  • deferredValue: 延迟更新的值,在初始渲染期间,返回的延迟值将与您提供的值相同

注意事项

useDeferredValue 接收到与之前不同的值(使用 Object.is 进行比较)时,除了当前渲染(此时它仍然使用旧值),它还会安排一个后台重新渲染。这个后台重新渲染是可以被中断的,如果 value 有新的更新,React 会从头开始重新启动后台渲染。举个例子,如果用户在输入框中的输入速度比接收延迟值的图表重新渲染的速度快,那么图表只会在用户停止输入后重新渲染。

案例:延迟搜索数据的更新

sh 复制代码
npm install mockjs antd
  • antd UI组件库
  • mockjs 模拟数据

以下示例展示了如何使用 useDeferredValue 延迟处理输入内容,以提高大型数据的搜索性能。

tsx 复制代码
import React, { useState, useTransition, useDeferredValue } from 'react'
import { Input, List } from 'antd'
import mockjs from 'mockjs'
interface Item {
   name: number
   address: string
}
export const App = () => {
   const [val, setVal] = useState('')
   const [list] = useState<Item[]>(() => {
    // 使用 Mock.js 生成模拟数据
      return mockjs.mock({
         'list|10000': [
            {
               'id|+1': 1,
               name: '@natural',
               'address': '@county(true)',
            }
         ]
      }).list
   })
   const deferredQuery = useDeferredValue(val)
   const isStale = deferredQuery !== val // 检查是否为延迟状态
   const findItem = () => {
      //过滤列表,仅在 deferredQuery 更新时触发
      return list.filter(item => item.name.toString().includes(deferredQuery))
   }
   return (
      <div>
         <Input value={val} onChange={(e) => setVal(e.target.value)} />
         <List style={{opacity: isStale ? '0.2' : '1', transition: 'all 1s'}} renderItem={(item) => <List.Item>
            <List.Item.Meta title={item.name} description={item.address} />
         </List.Item>} dataSource={findItem()}>
         </List>
      </div>
   )
}

export default App

效果

使用 useDeferredValue 后,输入框中的搜索内容不会立即触发列表过滤,避免频繁的渲染。输入停止片刻后(看起来像节流),列表会自动更新为符合条件的数据,确保了较流畅的交互体验。

陷阱

  • useDeferredValue 并不是防抖,防抖是需要一个固定的延迟时间,譬如1秒后再处理某些行为,但是useDeferredValue并不是一个固定的延迟,它会根据用户设备的情况进行延迟,当设备情况好,那么延迟几乎是无感知的
相关推荐
tedcloud12313 小时前
Wand-Enhancer:如何搭建一套远程开发与测试环境
前端·人工智能·macos·开源·流程图
掘金挖土13 小时前
前端手摸手跑路之 AI 应用开发(三)
前端·后端
计算机魔术师14 小时前
OpenAI 宣称破解千禧年难题,数学家却说是「反例搜索」?
前端
志尊宝14 小时前
Vue3 零基础每日笔记(015):条件渲染 v-if 与 v-show——控制 DOM 生死还是控制显隐
前端·vue.js·笔记
掘金者阿豪14 小时前
OceanBase 和金仓怎么选?别只看分布式,复杂查询更考验架构取舍
前端·后端·架构
Bug修理工Bubble14 小时前
Swift ARC:一个对象到底什么时候才会被释放?
前端
ClouGence14 小时前
GPT-6 做 UI 自动化测试:Demo 惊艳,但真的适合长期回归吗?
前端·chatgpt·测试
阿酷tony15 小时前
视频专栏列表的防录屏水印和跑马灯效果(也可网站调用)
java·前端·音视频
凌风的跨境分享15 小时前
Temu店群运维提效:定时策略自动化任务全场景实操指南
大数据·运维·前端·人工智能·架构·自动化
linux_cfan15 小时前
videojs v10 源代码系列解读:06 · DOM 工具箱:事件、聚焦、Shadow DOM、定位
前端