React 第二十三节 useTransition Hook 的使用注意事项详解

文章内容 基于 React 18+ ,如有错误,欢迎批评指正;

一、概述:

useTransition 是一个在不阻塞UI渲染 的情况下更新数据状态,它会降低 当前视图的渲染优先级 ,而优先执行视图中其它用户交互操作,比如 Tab切换、搜索加载等

二、特点:

1、可以保持当前UI的响应性 2、可以区分 队列任务的紧急优先级别 3、可以提供加载指示器 4、不会阻塞用户的交互操作

三、基本用法

javascript 复制代码
const [isPending, startTransition] = useTransition()

useTransition() 不接收任何参数, 返回参数: a、isPending: 告诉用户是否存在需要处理的transition; b、startTransition: 一个函数,可以将状态标记为 transtion,不返回任何值,并且传入的函数必须是**同步【React 18】**的【React 19 支持异步】,不能在里面执行 setTimeout/setInterval 等异步操作; 如:

javascript 复制代码
startTransition(() => {
    // 这里是一个函数
    setActivatedBar()
})

四、页签切换

比如在一个页签里面有大量数据需加载渲染 ,此时该页面的渲染必然会耗费很多 时间;当切换至其它tab时,必然会导致页面出现卡顿 现象,而出现点击下一个页签没有反应的假死现象 ; 假设 TabB 组件中有 100000条数据需要重组并渲染出来;

javascript 复制代码
export default function TabB() {
    let data = []
    for(let i=0;i<100000;i++){
        data.push({
            title: `标题${i+1}`,
            id: i,
            content: `内容:${String(Math.random() * 100 )}`
        })
    }
    return (
        <div>
            <ul>
            {
                data.map(itm => <li key={itm.id}>{itm.title}</li>)
            }
            </ul>
        
        </div>
    )
}

MyTransition 组件 当我们不使用 useTransition 时,tab之间的切换时页面会出现假死现象 ; 当使用 useTransition 时,即使当前 组件 TabB 在渲染过程中,我们依然可以切换下一个tab

javascript 复制代码
import { useTransition, useState } from 'react'
import TabA from './tabA'
import TabB from './tabB'
import TabC from './tabC'
import './index.scss'
export default function MyTransition() {
  const [activated, setActivated] = useState('A')
  const [isPending, startTransition] = useTransition()
  function handleTab(nextTab) {
    startTransition(() => {
      setActivated(nextTab)
    })
  }
  
  return (
    <div className='transition-box'>
      <div className='nav-box'>
        <button onClick={() => handleTab('A')} className={activated === 'A' ? 'activate' : ''}>TabA</button>
        <button onClick={() => handleTab('B')} className={activated === 'B' ? 'activate' : ''}>TabB</button>
        <button onClick={() => handleTab('C')} className={activated === 'C' ? 'activate' : ''}>TabC</button>
      </div>
      <div >
        { activated === 'A' && <TabA></TabA>  }
        { activated === 'B' && <TabB></TabB>  }
        { activated === 'C' && <TabC></TabC>  }
      </div>
    </div>
  )
}

TabA 与 TabC 组件

javascript 复制代码
export default function TabA() {
  return (
    <div>
      This is the  first content
    </div>
  )
}

export default function TabC() {
  return (
    <div>
      this is tab C content
    </div>
  )
}

五、使用场景

1、搜索输入建议 :用户连续输入时,延迟处理搜索逻辑。 2、路由切换 :预加载下一页数据时保持当前页响应。 3、表单分步提交 :后台处理提交逻辑时允许用户继续交互。 4、复杂渲染任务:如大型列表过滤、图表绘制。

六、注意事项:

1、被标记为 transition状态更新 ,会被其他状态更新打断 ,优先执行其他状态更新; 2、startTransition 的函数必须是同步执行 的,【React 19 中支持异步执行】这时React 会立即执行该函数,并且会将该函数执行过程中所有状态 标记为 transition , 3、transition 的更新不用于 控制文本输入; 4、被标记为 transition 的状态,更新是非阻塞 的,只是相对于其他状态降低 了更新优先级 5、useTransition 会导致两次 重新渲染,而不是一次 6、避免滥用 :仅对用户可感知的非紧急更新使用 (如搜索建议、后台数据加载;避免对即时反馈的操作(如按钮点击、表单提交)使用 ,否则会延迟必要反馈,破坏用户体验。 7、不要startTransition 中 执行网络请求定时器 等副作用;仅包裹状态更新,副作用应在 useEffect事件处理函数中执行 8、状态更新需要独立 :如果在 startTransition同时更新多个 状态,React 可能无法正确批处理,需要将多个状态 包裹在一个对象 中处理,或者使用 useReducer 管理复杂状态 9、与Suspense 结合时注意:若在 startTransition 中触发了 Suspense 回退(如懒加载组件),过渡期间会显示 fallback UI;可以通过 isPending 状态自定义加载提示,避免重复加载效果冲突 10、如果过渡任务过长时isPending 会导致加载提示长时间显示,需要使用 useDeferredValue优化后端请求,减少延迟时间

相关推荐
究极无敌暴龙战神X4 分钟前
哈希表 - 两个数组的交集(集合、数组) - JS
前端·javascript·散列表
前端御书房7 分钟前
基于 Trae 的超轻量级前端架构设计与性能优化实践
前端·性能优化
南部余额13 分钟前
playwright解决重复登录问题,通过pytest夹具自动读取storage_state用户状态信息
前端·爬虫·python·ui·pytest·pylawright
前端与小赵23 分钟前
webpack和vite之间的区别
前端·webpack·vite
zy01010127 分钟前
React受控表单绑定
前端·javascript·react.js·mvvm·双向数据绑定
百锦再27 分钟前
React编程的核心概念:数据流与观察者模式
前端·javascript·vue.js·观察者模式·react.js·前端框架·ecmascript
2401_8724878829 分钟前
网络安全之前端学习(css篇2)
前端·css·学习
SuperYing40 分钟前
前端候选人突围指南:让面试官主动追着要简历的五大特质(个人总结版)
前端·面试
前端双越老师42 分钟前
我的编程经验与认知
前端
linweidong1 小时前
前端Three.js面试题及参考答案
前端·javascript·vue.js·typescript·前端框架·three.js·前端面经