React的useTransition如何避免显示加载组件?
React useTransition 标签页示例中的状态“双值”现象解析
现象说明
React官方文档里的标签页示例,利用useTransition实现了这样的交互:切换标签时,新标签的内容加载完成前,页面始终显示旧标签的内容,加载完成后才切换到新标签。但实际运行时会出现一个特殊表现:负责切换的TabButtons组件能立刻感知到新的tab状态,更新选中按钮的样式;但页面中渲染标签内容的部分,却依然使用旧的tab值渲染——看起来同一JSX里的tab状态同时存在两个不同的值。
背后的原理
这其实是React的优先级更新机制和useTransition的设计逻辑共同作用的结果:
useTransition的核心作用是将状态更新标记为过渡更新(低优先级更新),这类更新会被延后处理,优先保证高优先级的用户交互反馈。- 当点击新标签时,React会优先处理高优先级的视觉反馈:也就是
TabButtons的样式更新(这部分属于用户交互后的即时视觉反馈,优先级最高),所以按钮能立刻拿到新的tab值,切换选中样式。 - 而标签内容的渲染,因为依赖异步加载的数据,且被
startTransition包裹的tab更新被标记为低优先级,React会暂时保留旧的tab值来渲染内容,直到数据加载完成,才会执行低优先级的状态更新,切换到新标签的内容。
核心代码逻辑
示例中的关键代码片段如下,体现了useTransition的使用方式:
import { useState, useTransition } from 'react'; function TabContainer() { const [isPending, startTransition] = useTransition(); const [tab, setTab] = useState('about'); const selectTab = (newTab) => { // 将tab的状态更新标记为过渡更新 startTransition(() => { setTab(newTab); }); }; return ( <div> <TabButtons tab={tab} onSelectTab={selectTab} isPending={isPending} /> {/* 内容渲染部分,会延迟使用新的tab值 */} {tab === 'about' && <AboutTab />} {tab === 'posts' && <PostsTab />} {tab === 'contact' && <ContactTab />} </div> ); }
这里的startTransition把setTab的更新包裹起来,告诉React:这个状态更新不需要立刻执行,先处理用户能立刻感知到的交互反馈(按钮样式),等数据准备好再更新内容。
内容的提问来源于stack exchange,提问作者Plumpie
相关产品推荐
相关产品推荐

