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

学习React-10-useTransition

useTransition

useTransition 是 React 中的一个 Hook,用于标记非紧急的状态更新,允许在并发模式下延迟渲染,避免阻塞高优先级的交互(如用户输入或动画)。它返回一个包含 isPending 标志和 startTransition 函数的数组

基本用法
const [isPending, startTransition] = useTransition();
  • isPending:布尔值,表示是否有过渡中的状态更新未完成。
  • startTransition:函数,用于包裹非紧急的状态更新。
使用场景
  1. 优化渲染性能:将耗时的状态更新(如大型列表筛选)标记为低优先级,避免页面卡顿。
  2. 用户输入响应:确保输入框等高优先级交互的即时响应,延迟其他次要更新。
小栗子

需求: 实现输入框输入内容的模糊检索功能。
前置工具:mockjs、AntDesigin

编写api插件 vite.config.ts

// 导入 Vite 核心配置函数
import { defineConfig } from 'vite'
// 导入 React SWC 插件,提供快速的 React 支持和热更新
import react from '@vitejs/plugin-react-swc'
// 导入 Vite 插件类型定义
import type { Plugin } from 'vite'
// 导入 Mock.js 用于生成模拟数据
import mockjs from 'mockjs'
// 导入 Node.js url 模块用于解析 URL
import url from 'node:url'/*** 自定义 Vite Mock 服务插件* 功能:在开发环境下提供 API 模拟服务* 用途:前端开发时无需依赖真实后端 API,可以使用模拟数据进行开发和测试*/
const viteMockService = (): Plugin => {return {// 插件名称,用于调试和识别name: 'vite-mock-service',/*** 配置开发服务器* @param server Vite 开发服务器实例*/configureServer(server) {/*** 注册 API 路由中间件* 路径:/api/list* 功能:返回包含1000条模拟数据的列表*/server.middlewares.use('/api/list', (req, res) => {// 设置响应头为 JSON 格式res.setHeader('Content-Type', 'application/json')// 解析请求 URL 中的查询参数// url.parse(原始地址, 是否格式化查询参数为对象)const parseUrl = url.parse(req.originalUrl, true).query/*** 使用 Mock.js 生成模拟数据* 数据结构:* - list: 包含1000个对象的数组* - 每个对象包含:id(自增)、name(来自查询参数)、address(随机地址)*/const data = mockjs.mock({'list|1000': [ // 生成1000条数据{'id|+1': 1,              // id 字段,从1开始自增name: parseUrl.keyWord,   // name 字段,使用查询参数中的 keyWord 值'address': '@county(true)' // address 字段,生成随机的完整县级地址}]})// 将模拟数据转换为 JSON 字符串并返回给客户端res.end(JSON.stringify(data))})}}
}/*** Vite 配置* 官方文档:https://vite.dev/config/*/
export default defineConfig({/*** 插件配置* - react(): 提供 React 支持,使用 SWC 编译器实现快速构建和热更新* - viteMockService(): 自定义 Mock 服务插件,提供开发环境下的 API 模拟*/plugins: [react(), viteMockService()],
})

编写component组件 index.tsx

import React, { useState, useTransition } from 'react'
import { Input, List } from 'antd'// 定义列表项数据类型
interface ResultType {id: number      // 唯一标识符name: string    // 名称address: string // 地址
}/*** 使用 useTransition 的搜索列表组件* 功能:根据输入关键词搜索并展示地址包含名称的数据项* 特性:使用 React 18 的 useTransition 优化用户体验*/
export function UseTransition() {// 输入框内容状态const [val, setVal] = useState('')// 返回地址列表状态const [list, setList] = useState<ResultType[]>([])// 使用 useTransition 处理非紧急状态更新,避免阻塞用户交互const [isPending, startTransition] = useTransition()/*** 处理输入框内容变化* @param e - 输入框变化事件*/const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {const value = e.target.value// 立即更新输入框内容(紧急更新)setVal(value)// 发起 API 请求获取搜索结果fetch(`api/list/keyWord?keyWord=${value}`).then(res => res.json()).then(res => {// 使用 startTransition 包装列表更新(非紧急更新)// 这样可以避免搜索结果更新时阻塞输入框的响应startTransition(() => {setList(res.list)})// 注释:不使用 startTransition 的传统方式// setList(res.list)})}return (<div>{/* 搜索输入框 */}<Input value={val} onChange={handleChange} />{/* 搜索结果列表 */}<List // 过滤数据:只显示地址包含名称的项目dataSource={list.filter(item => item.address.includes(item.name))} // 显示加载状态,当 transition 正在进行时显示loading={isPending}// 渲染每个列表项renderItem={(item: ResultType) => (<List.Item><List.Item.Meta title={item.name}        // 显示名称作为标题description={item.address} // 显示地址作为描述/></List.Item>)}/></div>)
}

使用useTransition对比效果:

注意事项
  1. 滥用 useTransition
    将所有的状态更新都包裹在 useTransition 中,会导致性能优化失效,甚至可能增加不必要的开销。
 /* ---------- 1. 滥用:把所有同步更新也包起来 ---------- */function handleClick1() {// ❌ 同步更新根本没必要用 transition,反而多一次调度startTransition(() => {setPage('/about');});}
  1. 忽略 isPending 状态
    未使用 isPending 提供加载反馈,导致用户无法感知过渡状态,影响用户体验。
/* ---------- 2. 忽略 isPending:用户看不到加载指示 ---------- */function handleClick2() {startTransition(() => {// 假装拉数据fetch('/api/list').then((r) => r.json()).then((data) => setList(data));});// ❌ 这里没用到 isPending,按钮不会转圈,用户以为卡死
  1. 在同步任务中使用
    useTransition 仅适用于异步状态更新(如数据获取),在同步任务中使用无意义。
/* ---------- 3. 在纯同步任务里用 transition ---------- */function handleClick3() {// ❌ 下面这段代码没有任何异步,包 transition 等于空转startTransition(() => {const next = list.length + 1;setList((l) => [...l, next]);});}
  1. 未正确处理错误
    过渡期间未捕获潜在错误,可能导致应用崩溃或状态不一致。
  /* ---------- 4. 过渡期间不 catch 错误 ---------- */function handleClick4() {startTransition(() => {// ❌ 一旦接口挂掉,异常会向上冒泡,整棵组件树可能白屏fetch('/api/unsafe').then((r) => r.json()).then((d) => setList(d));});}
  1. 嵌套或过度组合
    在复杂组件中嵌套多个 useTransition,可能导致逻辑混乱和性能问题。
 /* ---------- 5. 嵌套 / 过度组合 ---------- */function handleClick5() {// ❌ 嵌套两层 transition,逻辑难读,调度成本翻倍startTransition(() => {setPage('/shop');startTransition(() => {setList([]);});});}

文章转载自:

http://q8teJTOD.rcjyc.cn
http://kmETUxey.rcjyc.cn
http://z2DgSm2j.rcjyc.cn
http://oMWYCNo7.rcjyc.cn
http://u61q0ZHg.rcjyc.cn
http://nErdIQc8.rcjyc.cn
http://rhZ8Wkgm.rcjyc.cn
http://nCWRG9Vr.rcjyc.cn
http://lxHJIpsr.rcjyc.cn
http://zyosFrHT.rcjyc.cn
http://Q0Ci1QBb.rcjyc.cn
http://ROgz0rWj.rcjyc.cn
http://7DLqZ8en.rcjyc.cn
http://ds1VIhzH.rcjyc.cn
http://r7JhGYwa.rcjyc.cn
http://eJ9DWmBK.rcjyc.cn
http://lFHKNGmq.rcjyc.cn
http://wlTOhVQY.rcjyc.cn
http://lg4E4lEw.rcjyc.cn
http://jiprEugA.rcjyc.cn
http://ZzXY4K41.rcjyc.cn
http://41HxJnuw.rcjyc.cn
http://WrjP4nSw.rcjyc.cn
http://9osteWuL.rcjyc.cn
http://usLrcoRt.rcjyc.cn
http://vuoRLufV.rcjyc.cn
http://PrcEUg2u.rcjyc.cn
http://3ddXuVtP.rcjyc.cn
http://THUA7h8j.rcjyc.cn
http://0QKVERbC.rcjyc.cn
http://www.dtcms.com/a/376510.html

相关文章:

  • Hive中的3种虚拟列以及Hive如何进行条件判断
  • 基于 C++ 的 IEC60870-5-104 规约的主从站模拟数据通信
  • css flex布局,设置flex-wrap:wrap换行后,如何保证子节点被内容撑高后,每一行的子节点高度一致。
  • 一款免费开源轻量的漏洞情报系统 | 漏洞情报包含:组件漏洞 + 软件漏洞 + 系统漏洞
  • 容器问答题上
  • uniapp发布成 微信小程序 主包内 main.wxss 体积太大
  • Uniapp中使用renderjs实现OpenLayers+天地图的展示与操作
  • 鸿蒙HAP包解包、打包、签名及加固全流程解析
  • [Leetcode 算法题单] 1456. 定长子串中元音的最大数目
  • 基于Springboot + vue实现的高校大学生竞赛项目管理系统
  • 为什么 socket.io 客户端在浏览器能连上,但在 Node.js 中报错 transport close?
  • Windows 命令行:切换盘符
  • 论文阅读记录之《VelocityGPT 》
  • 微服务通信实战篇:基于 Feign 的远程调用与性能优化
  • “双轮”驱动见成效 中和农信深耕乡村“最后一百米”
  • 高防IP怎样抵御CC攻击的频繁侵扰?
  • LeetCode 面试经典 150_矩阵_生命游戏(38_289_C++_中等)(额外状态)
  • Kotlin 2.2.20 现已发布!下个版本的特性抢先看!
  • Shell编程:计算鸡兔同笼问题
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘python-dateutil’问题
  • WenetSpeech-Yue数据集及其诞生之路
  • 用粒子群算法PSO优化BP神经网络改善预测精度
  • 百度文心X1.1发布!实测深度思考能力!
  • 第六篇:终极压力测试——故障注入测试(FIT)
  • 文心大模型 X1.1:百度交出的“新深度思考”答卷
  • 物联网平台中的MongoDB(二)性能优化与生产监控
  • 性能测试-jmeter9-逻辑控制器、定时器压力并发
  • 网络编程;TCP控制机械臂;UDP文件传输;0910;ps今天没写出来
  • Firefox Window 开发详解(一)
  • 无公网 IP 也能轻松访问家中群晖 NAS:神卓 NAT 盒子使用记