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

2.0 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
Use useTransition Over Manual Loading States LOW 减少重新渲染并提升代码清晰度 rendering, transitions, useTransition, loading, state

使用 useTransition 替代手动加载状态

使用 useTransition 替代手动的 useState 来管理加载状态。它提供了内置的 isPending 状态,并自动管理过渡过程。

错误做法(手动加载状态):

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 状态):

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