Yasin

Yasin

React startTransition使用

startTransition

React 18 引入的 API,用于将某些状态更新标记为低优先级的过渡更新(Transition),与高优先级的紧急更新区分开来。


核心概念

React 将更新分为两类:

类型 例子 优先级
紧急更新 输入框打字、按钮点击、滚动 高,立即响应
过渡更新 搜索结果渲染、页面切换、图片加载后的 UI 变化 低,可被中断

行为特性

1. 可中断性
过渡更新可以被新的紧急更新打断。比如用户在搜索时继续打字,React 会放弃上一次过渡渲染,优先处理新的输入。

2. 不会阻塞 UI
紧急更新始终优先执行,过渡更新在空闲时处理,页面不会卡顿。

3. 批量合并
startTransition 内的多个 setState 会被合并为一次渲染。


使用方式

import { startTransition } from "react";

// 方式一:直接调用(无 isPending 状态)
startTransition(() => {
  setTab("settings");
  setData(newData);
});

// 方式二:useTransition hook(可获取 pending 状态)
const [isPending, startTransition] = useTransition();

startTransition(() => {
  setTab("settings");
});

// isPending 为 true 时可显示 loading 指示器
{
  isPending && <Spinner />;
}

在你的代码中的作用

SmartAvataruseEffect 里同步调用 setState 会触发级联渲染警告。用 startTransition 包裹后:

useEffect(() => {
  if (!target) {
    startTransition(() => setLoaded(false)); // 标记为低优先级
    return;
  }
  // ...
}, [target]);

React 将这些状态变更视为过渡更新,不会在 effect 执行阶段立即触发同步重渲,从而消除级联渲染问题。


useDeferredValue 的区别

startTransition useDeferredValue
控制对象 状态更新 的优先级 的更新延迟
使用场景 你控制 setState 的地方 你接收 props/state 但无法控制其来源