Skip to content

React 20 併發特性成熟

React 20 的併發特性不再是實驗性功能。useTransitionuseDeferredValue 和新的調度 API 全部進入穩定版,並且在底層做了大量性能優化。對於需要處理大量用户交互的複雜應用,這些特性終於可以放心用了。

useTransition 的實際應用

useTransition 最常見的用法是讓路由切換或大數據過濾不阻塞輸入。React 20 優化了 transition 的調度粒度,低優先級更新不再被高優先級長時間餓死。

javascript
import { useState, useTransition, Suspense } from 'react';

function SearchableProductList({ products }) {
  const [filter, setFilter] = useState('');
  const [isPending, startTransition] = useTransition();

  const handleFilter = (e) => {
    // 立即更新輸入框(高優先級)
    setFilter(e.target.value);

    // 過濾計算放到 transition 中(低優先級)
    startTransition(() => {
      setFilteredProducts(
        products.filter(p =>
          p.name.toLowerCase().includes(e.target.value.toLowerCase())
        )
      );
    });
  };

  const filtered = products.filter(p =>
    p.name.toLowerCase().includes(filter.toLowerCase())
  );

  return (
    <div>
      <input
        type="text"
        value={filter}
        onChange={handleFilter}
        placeholder="搜索產品..."
      />
      <div style={{ opacity: isPending ? 0.7 : 1, transition: 'opacity 150ms' }}>
        <ProductGrid products={filtered} />
      </div>
      {isPending && <Spinner position="top-right" />}
    </div>
  );
}

React 20 的改進在於:transition 內的狀態更新可以中斷和恢復。當你連續快速輸入時,React 會丟棄中間的過時計算,只執行最後一次。

useDeferredValue 的自動記憶化

useDeferredValue 在 React 20 中獲得了編譯器優化的支持。它不再簡單地延遲值傳遞,而是與 React Compiler 協作,只重新渲染真正需要更新的子樹。

javascript
import { useState, useDeferredValue, memo } from 'react';

// React 20 Compiler 會自動優化這個組件
// 不需要手動寫 memo
function ProductGrid({ products }) {
  return (
    <div className="grid">
      {products.map(p => (
        <ProductCard key={p.id} product={p} />
      ))}
    </div>
  );
}

function App() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);

  // 當 query 變化時,input 立即更新
  // filteredProducts 使用 deferredQuery,更新被延遲
  const filteredProducts = useMemo(
    () => filterProducts(deferredQuery),
    [deferredQuery]
  );

  return (
    <div>
      <input value={query} onChange={e => setQuery(e.target.value)} />
      <ProductGrid products={filteredProducts} />
    </div>
  );
}

關鍵變化是 useDeferredValue 現在支持自定義比較函數:

javascript
// React 20 新增:自定義比較邏輯
const deferredQuery = useDeferredValue(query, {
  // 只有當值變化超過 300ms 才認為是新的 deferred 值
  timeoutMs: 300,
  // 自定義相等性檢查
  isEqual: (prev, next) => prev.trim() === next.trim(),
});

Scheduler API:自定義優先級

React 20 暴露了底層調度 API,讓你可以為特定更新指定優先級。這在複雜交互場景中非常有用:

javascript
import { unstable_scheduleUpdate, Priority } from 'react-scheduler';

function DragDropBoard() {
  const handleDrag = (item, position) => {
    // 拖拽時的實時反饋:最高優先級
    unstable_scheduleUpdate({
      priority: Priority.Immediate,
      task: () => updateDragPosition(item, position),
    });
  };

  const handleDrop = (item, targetList) => {
    // 放下後的數據同步:普通優先級
    unstable_scheduleUpdate({
      priority: Priority.Normal,
      task: () => persistDropOperation(item, targetList),
    });

    // 後台統計更新:最低優先級
    unstable_scheduleUpdate({
      priority: Priority.Idle,
      task: () => trackAnalytics('item_moved', { item, targetList }),
    });
  };

  return <Board onDrag={handleDrag} onDrop={handleDrop} />;
}

Priority 級別:Immediate > UserBlocking > Normal > Low > Idle。在實際項目中,建議只在拖拽、遊戲、實時協作等對延遲敏感的場景中使用自定義優先級。

併發模式下的表單優化

React 20 的併發特性與新表單 API 完美配合。輸入框的即時響應和後端驗證的延遲執行天然分離:

javascript
import { useState, useTransition } from 'react';
import { useField } from 'react';

function AsyncValidationInput() {
  const [isPending, startTransition] = useTransition();

  const field = useField({
    name: 'username',
    onChange: (value) => {
      // 輸入更新是同步的(高優先級)
      // 驗證在 transition 中(低優先級,可中斷)
      startTransition(() => {
        validateUsername(value);
      });
    },
  });

  return (
    <div>
      <input {...field.inputProps} />
      {isPending && <span className="hint">檢查用户名可用性...</span>}
      {field.error && <span className="error">{field.error}</span>}
    </div>
  );
}

小結

  • useTransition 調度粒度更細,連續快速輸入時自動丟棄過時更新
  • useDeferredValue 支持自定義比較函數和超時控制,與 Compiler 協作優化渲染
  • Scheduler API 暴露底層優先級控制,適合拖拽/遊戲等高交互場景
  • 併發特性與 Actions v2、新表單 API 深度集成,形成完整的響應式體系
  • 併發模式不再是「實驗性功能」,而是 React 20 處理複雜交互的標準方案

MIT Licensed