Files
skillhub-088-vercel-react-b…/rules/rendering-usetransition-loading.md
2026-07-13 21:36:17 +08:00

76 lines
2.0 KiB
Markdown

---
title: Use useTransition Over Manual Loading States
impact: LOW
impactDescription: 减少重新渲染并提升代码清晰度
tags: rendering, transitions, useTransition, loading, state
---
## 使用 useTransition 替代手动加载状态
使用 `useTransition` 替代手动的 `useState` 来管理加载状态。它提供了内置的 `isPending` 状态,并自动管理过渡过程。
**错误做法(手动加载状态):**
```tsx
function SearchResults() {
const [query, setQuery] = useState('')
const [results, setResults] = useState([])
const [isLoading, setIsLoading] = useState(false)
const handleSearch = async (value: string) => {
setIsLoading(true)
setQuery(value)
const data = await fetchResults(value)
setResults(data)
setIsLoading(false)
}
return (
<>
<input onChange={(e) => handleSearch(e.target.value)} />
{isLoading && <Spinner />}
<ResultsList results={results} />
</>
)
}
```
**正确做法(useTransition 配合内置 pending 状态):**
```tsx
import { useTransition, useState } from 'react'
function SearchResults() {
const [query, setQuery] = useState('')
const [results, setResults] = useState([])
const [isPending, startTransition] = useTransition()
const handleSearch = (value: string) => {
setQuery(value) // 立即更新输入框
startTransition(async () => {
// 获取数据并更新结果
const data = await fetchResults(value)
setResults(data)
})
}
return (
<>
<input onChange={(e) => handleSearch(e.target.value)} />
{isPending && <Spinner />}
<ResultsList results={results} />
</>
)
}
```
**优势:**
- **自动 pending 状态**:无需手动管理 `setIsLoading(true/false)`
- **错误韧性**:即使过渡过程抛出异常,pending 状态也能正确重置
- **更好的响应性**:在更新期间保持 UI 响应
- **中断处理**:新的过渡会自动取消正在进行的过渡
参考文档:[useTransition](https://react.dev/reference/react/useTransition)