76 lines
2.0 KiB
Markdown
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)
|