startTransition
是 React 18 引入的核心 API 之一,可以让你在后台渲染 UI 的一部分。用于标记某些状态更新为非紧急优先级,允许 React 在不阻塞 UI 渲染的情况下处理这些更新。这一特性显著提升了复杂应用的响应性和用户体验。
核心概念与原理
在 React 18 中,渲染分为两种优先级:
- 紧急更新(Urgent Updates):如点击、输入等直接交互,需要立即响应。
- 过渡更新(Transition Updates):如页面导航、数据加载等不需要立即完成的更新。
startTransition
的作用是将紧急更新转变为过渡更新,允许 React 在用户交互期间继续保持界面响应,而不是被耗时的渲染任务阻塞。
基本用法
你可以通过将一个 state 包裹在 startTransition
回调中,将其更新标记为一个 transition:
这里以搜索框优化为例:
javascript
import { useState, startTransition } from 'react';
function SearchComponent() {
const [inputValue, setInputValue] = useState('');
const [searchResults, setSearchResults] = useState([]);
const handleInputChange = (e) => {
const value = e.target.value;
// 紧急更新:立即更新输入框值
setInputValue(value);
// 过渡更新:延迟更新搜索结果
startTransition(() => {
setSearchResults(fetchResults(value));
});
};
return (
<div>
<input value={inputValue} onChange={handleInputChange} />
<SearchResults results={searchResults} />
</div>
);
}
注意事项:
- 传递给
startTransition
的函数会被立即执行,并将在其执行期间发生的所有状态更新标记为 transition。如果你尝试在setTimeout
中执行状态更新,它们将不会被标记为 transition。 - 只有在可以访问该状态的
set
函数时,才能将其对应的状态更新包装为 transition。如果你想启用 Transition 以响应某个 prop 或自定义 Hook 值,请尝试使用useDeferredValue
。 - 标记为 Transition 的状态更新将被其他状态更新打断。例如在 Transition 中更新图表组件,并在图表组件仍在重新渲染时继续在输入框中输入,React 将首先处理输入框的更新,之后再重新启动对图表组件的渲染工作。
- Transition 更新不能用于控制文本输入。
使用场景
- 复杂渲染更新:如长列表、图表等需要大量计算的渲染。
- 导航与路由切换:页面切换时保持界面响应。
- 数据获取与加载:在等待数据时允许用户继续交互。
- 状态批量更新:合并多个状态更新,减少渲染次数。
useTransition 与 startTransition 的区别
特性 | useTransition |
startTransition |
---|---|---|
类型 | React Hook | 独立函数 |
返回值 | [isPending, startTransition] |
无返回值 |
Pending 状态 | 提供 isPending 状态指示器 |
不提供状态指示器 |
使用场景 | 组件内部 | 组件外部或事件处理函数中 |
依赖关系 | 需要 React 18+ 和并发模式 | 需要 React 18+ |
典型用例 | UI 加载状态指示 | 库/工具函数中的状态更新 |
通过合理使用 startTransition
,可以让你的 React 应用在处理复杂渲染时保持流畅的用户体验,达到接近原生应用的响应速度。