当前位置: 首页 > news >正文

react 的 useTransition 、useDeferredValue

useTransition

用于 管理状态更新的过渡(pending)状态,避免因高优先级任务(如用户输入)被低优先级任务(如数据获取或复杂计算)阻塞而导致的界面卡顿。
它特别适用于,需要 区分紧急更新和非紧急更新 的场景。

useTransition 的核心作用

  • 标记非紧急更新:
    1、允许某些状态更新(如:数据获取、复杂计算)被标记为“过渡”(startTransition),让 React 知道这些更新可以延迟执行。
    2、紧急更新(如用户输入、动画)会优先执行,避免界面卡顿。

  • 显示加载状态:
    在过渡期间,可以显示一个加载指示器(如骨架屏、旋转图标),提升用户体验。

  • 避免不必要的渲染:
    如果过渡更新被更高优先级的更新打断,React 会丢弃未完成的过渡更新,避免浪费资源。

基本用法

import { useState, useTransition } from 'react'function App() {const [ isPending, startTransition ] = useTransition()const [ list, setList ] = useState([])const [ inputValue, setInputValue ] = useState('')const handleInputChange = (e) => {setInputValue(e.target.value) // 紧急更新(用户输入)}const handleSearch = () => {startTransition(() => {// 模拟一个耗时的数据获取操作const newList = fetchData(inputValue) // 非紧急更新(数据获取)setList(newList)})}return (<div><inputtype="text"value={inputValue}onChange={handleInputChange}/><button onClick={handleSearch}>Search</button>{isPending && <p>Loading...</p>}  {/* 显示加载状态 */}<ul>{list.map((item) => (<li key={item.id}>{item.name}</li>))}</ul></div>) // end-return
}// 模拟数据获取
function fetchData(query) {// 假设这是一个耗时操作(如 API 请求)return Array.from({ length: 1000 }, (_, i) => ({id: i,name: `${query} Item ${i}`,}))
}
  • 解析
  1. useTransition 返回一个数组:
    isPending:布尔值,表示是否有未完成的过渡更新。
    startTransition:函数,用于标记某个状态更新为“过渡”。

  2. 紧急更新 vs. 过渡更新:
    紧急更新(如 setInputValue)会立即执行,不会被延迟。
    过渡更新(如 setList)会被标记为低优先级,React 会在空闲时执行。

  3. isPending 的作用
    在过渡期间,isPending 为 true,可以用于显示加载状态(如 Loading…)。

  4. startTransition 的使用
    将耗时操作包裹在 startTransition 中,告诉 React 这是非紧急更新。

总之

  • useTransition 是 React 18 提供的优化工具,用于 区分紧急和非紧急更新,避免界面卡顿。
  • isPending 可以用于显示加载状态,提升用户体验。
  • startTransition 用于标记非紧急更新,让 React 知道可以延迟执行。

如果你的应用中有 耗时操作(如:数据获取、复杂计算),并且希望 避免阻塞用户交互useTransition 是一个非常好的选择! 🚀




useDeferredValue

useDeferredValue 的核心作用

  1. 延迟低优先级更新

    • 当某个状态(如:输入框的值)变化时,React 会优先处理高优先级任务(如:用户输入),而延迟处理低优先级任务(如:列表渲染)。
    • 避免因列表渲染导致输入框卡顿。
  2. 自动管理优先级

    • 不需要手动调用 startTransitionuseDeferredValue 会自动决定何时延迟更新。
  3. 避免不必要的渲染

    • 如果输入值快速变化(如:用户连续输入),React 会丢弃未完成的低优先级更新,避免浪费资源。

基本用法

import { useState, useDeferredValue } from 'react'function SearchResults() {const [ query, setQuery ] = useState('')const deferredQuery = useDeferredValue(query)  // 延迟更新后的值const [ list, setList ] = useState([])// 模拟数据获取(耗时操作)const fetchData = (q) => {return Array.from({ length: 1000 }, (_, i) => ({id: i,name: `${q} Item ${i}`,}))}// 当 deferredQuery 变化时,更新列表// (但不会阻塞用户输入)React.useEffect(() => {setList(fetchData(deferredQuery))}, [deferredQuery])return (<div><inputtype="text"value={query}onChange={(e) => setQuery(e.target.value)}placeholder="Search..."/><ul>{list.map((item) => (<li key={item.id}>{item.name}</li>))}</ul></div>) // end-return
}
  1. useDeferredValue 返回一个延迟的值

    • deferredQueryquery 的延迟版本,React 会在空闲时更新它。
    • 用户输入(query 变化)是紧急更新,会立即响应。
    • 列表渲染(基于 deferredQuery)是低优先级更新,会延迟执行。
  2. 自动优化性能

    • 如果用户快速输入,React 会丢弃未完成的 deferredQuery 更新,避免浪费资源。
    • 只有当用户停止输入或输入速度变慢时,才会执行低优先级更新。
  3. 适用场景

    • 搜索框 + 动态列表:用户输入时,列表渲染不会阻塞输入。
    • 过滤/排序大数据:用户调整筛选条件时,列表更新不会卡顿。

优化后的代码示例(带加载状态)

import { useState, useDeferredValue, useEffect } from 'react'function SearchResults() {const [ query, setQuery ] = useState('')const deferredQuery = useDeferredValue(query)const [ list, setList ] = useState([])const [ isLoading, setIsLoading ] = useState(false)useEffect(() => {setIsLoading(true)const timer = setTimeout(() => {setList(Array.from({ length: 1000 }, (_, i) => ({id: i,name: `${deferredQuery} Item ${i}`,})))setIsLoading(false)}, 300)return () => clearTimeout(timer)  // 清理未完成的更新}, [deferredQuery])return (<div><inputtype="text"value={query}onChange={(e) => setQuery(e.target.value)} />{isLoading && <p>Loading...</p>}<ul>{list.map((item) => (<li key={item.id}>{item.name}</li>))}</ul></div>) // end-return
}

总结

  • useDeferredValue 是 React 18 提供的优化工具,用于 延迟低优先级状态更新,避免阻塞用户交互。
  • 适用场景:输入框关联的动态内容(如搜索建议、过滤列表)。
  • 优势
    • 自动管理优先级,无需手动调用 startTransition
    • 避免因低优先级任务导致界面卡顿。
    • 提升用户体验,特别是在输入场景下。

如果你的应用中有 输入框 + 动态列表 的交互,useDeferredValue 是一个非常合适的优化方案! 🚀

http://www.dtcms.com/a/304483.html

相关文章:

  • ZKmall开源商城架构工具链:Docker、k8s 部署与管理技巧
  • 反射核心:invoke与setAccessible方法详解
  • SpringBoot整合RocketMQ(阿里云ONS)
  • 数据库4.0
  • Linux 文件管理高级操作:复制、移动与查找的深度探索
  • Deep Research(信息检索增强)认识和项目实战
  • 计算器4.0:新增页签功能梳理页面,通过IO流实现在用户本地存储数据
  • 点控云数据洞察智能体:让房地产决策有据可循,让业务增长稳健前行
  • 【LLM】——qwen2.5 VL模型导出到onnx
  • Python中二进制文件操作
  • 快速了解逻辑回归
  • 【华为机试】43. 字符串相乘
  • 【LeetCode 随笔】
  • 【深度学习】独热编码(One-Hot Encoding)
  • 开源 Arkts 鸿蒙应用 开发(十一)证书和包名修改
  • C语言在键盘上输入一个3行3列矩阵的各个元素的值(值为整数),然后输出主对角线元素的积,并在fun()函数中输出。
  • 信号上升时间与带宽的关系
  • Leetcode-3361两个字符串的切换距离
  • FastAPI入门:请求体的字段、嵌套模型、额外数据、额外数据类型
  • Linux系统部署k8s集群
  • 在 Web3 时代通过自我主权合规重塑 KYC/AML
  • Git快速入门,完整的git项目管理工具教程,git入门到精通!
  • 青少年软件编程图形化Scratch等级考试试卷(二级)2025年6月
  • 【EDA】Calma--早期版图绘制工具商
  • python案例:基于python 神经网络cnn和LDA主题分析的旅游景点满意度分析
  • 解决mac下git pull、push需要输入密码
  • 半导体企业选用的跨网文件交换系统到底应该具备什么功能?
  • 【007TG洞察】美欧贸易新政下跨境业务的技术破局:从数据治理到智能触达的全链路重构
  • SpringBoot整合RocketMQ(rocketmq-client.jar)
  • 小程序中事件对象的属性与方法