什么是 useTransition
?
useTransition
是一个 Hook,用于标记某些状态更新为“过渡”(Transition),告诉 React 这些更新不是紧急的,可以延迟执行。这样 React 可以优先处理高优先级的任务(比如用户输入),避免界面卡顿。
- 返回值:一个数组
[isPending, startTransition]
。isPending
:布尔值,表示过渡是否正在进行。startTransition
:一个函数,用于包裹低优先级的状态更新。
- 核心作用:区分紧急更新和高优先级更新,提升应用的响应性。
如何使用 useTransition
?
以下是基本步骤和语法:
1. 引入并调用 useTransition
import { useTransition } from 'react';
function MyComponent() {
const [isPending, startTransition] = useTransition();
// ...
}
2. 使用 startTransition
包裹状态更新
将低优先级的状态更新放入 startTransition
函数中:
startTransition(() => {
setSomeState(newValue); // 低优先级更新
});
3. 使用 isPending
显示加载状态(可选)
当过渡正在进行时,isPending
为 true
,可以用来显示加载指示器:
return isPending ? <div>Loading...</div> : <div>{someState}</div>;
代码示例
下面是一个完整的例子,展示如何使用 useTransition
优化搜索过滤场景:
import { useState, useTransition } from 'react';
function SearchList() {
const [query, setQuery] = useState('');
const [filteredList, setFilteredList] = useState([]);
const [isPending, startTransition] = useTransition();
// 模拟一个大数据列表
const largeList = Array.from({ length: 10000 }, (_, i) => `Item ${i}`);
const handleChange = (e) => {
const value = e.target.value;
setQuery(value); // 高优先级更新:输入框实时响应
// 低优先级更新:过滤列表
startTransition(() => {
const filtered = largeList.filter(item => item.includes(value));
setFilteredList(filtered);
});
};
return (
<div>
<input
type="text"
value={query}
onChange={handleChange}
placeholder="Search..."
/>
{isPending && <div>Filtering...</div>}
<ul>
{filteredList.slice(0, 100).map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}
export default SearchList;
运行效果解释:
- 输入时:
setQuery
是高优先级更新,输入框会立即反映用户输入。 - 过滤时:
setFilteredList
被包裹在startTransition
中,React 会延迟处理这个更新,避免阻塞输入。 - 加载状态:
isPending
为true
时显示“Filtering...”,提示用户过滤正在进行。
使用场景
- 大数据处理:比如过滤或排序大型列表时,避免界面卡顿。
- 复杂 UI 更新:如动态加载大量组件或计算密集型操作。
- 搜索或筛选功能:实时响应用户输入,同时延迟更新结果展示。
注意事项
-
不是所有更新都需要
useTransition
只有当状态更新可能影响性能或用户体验时,才使用startTransition
。普通的小规模更新无需此优化。 -
与 Suspense 的关系
useTransition
可以与 Suspense 配合使用。例如,在等待数据加载时,使用startTransition
标记状态更新,结合<Suspense>
显示 fallback。 -
浏览器支持
useTransition
依赖 React 18 的并发特性,确保项目使用的是 React 18 及以上版本。
扩展示例:结合 Suspense
以下是一个结合 Suspense 的例子,模拟延迟加载数据:
import { useState, useTransition, Suspense } from 'react';
function fetchData(query) {
return new Promise(resolve => {
setTimeout(() => resolve(`Result for ${query}`), 1000);
});
}
function DataComponent({ resource }) {
return <div>{resource}</div>;
}
function App() {
const [query, setQuery] = useState('');
const [resource, setResource] = useState(null);
const [isPending, startTransition] = useTransition();
const handleChange = (e) => {
const value = e.target.value;
setQuery(value);
startTransition(() => {
setResource(fetchData(value)); // 模拟异步数据获取
});
};
return (
<div>
<input value={query} onChange={handleChange} />
{isPending ? (
<div>Loading...</div>
) : (
<Suspense fallback={<div>Fetching...</div>}>
{resource && <DataComponent resource={resource} />}
</Suspense>
)}
</div>
);
}
export default App;
效果:
- 输入框实时更新。
- 数据获取被标记为过渡状态,
isPending
显示“Loading...”。 - Suspense 的
fallback
在数据加载时显示“Fetching...”。
总结
useTransition
是 React 18 中用于优化性能的强大工具。通过将低优先级更新放入 startTransition
,配合 isPending
提供反馈,可以显著提升应用的流畅度和用户体验。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Blazor Hybrid适配到HarmonyOS系统
· 支付宝 IoT 设备入门宝典(下)设备经营篇
· 万字调研——AI生成内容检测
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库