joken-前端工程师

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::
  378 随笔 :: 39 文章 :: 8 评论 :: 20万 阅读

什么是 useTransition

useTransition 是一个 Hook,用于标记某些状态更新为“过渡”(Transition),告诉 React 这些更新不是紧急的,可以延迟执行。这样 React 可以优先处理高优先级的任务(比如用户输入),避免界面卡顿。

  • 返回值:一个数组 [isPending, startTransition]
    • isPending:布尔值,表示过渡是否正在进行。
    • startTransition:一个函数,用于包裹低优先级的状态更新。
  • 核心作用:区分紧急更新和高优先级更新,提升应用的响应性。

如何使用 useTransition

以下是基本步骤和语法:

1. 引入并调用 useTransition

import { useTransition } from 'react';

function MyComponent() {
  const [isPending, startTransition] = useTransition();
  // ...
}

2. 使用 startTransition 包裹状态更新

将低优先级的状态更新放入 startTransition 函数中:

startTransition(() => {
  setSomeState(newValue); // 低优先级更新
});

3. 使用 isPending 显示加载状态(可选)

当过渡正在进行时,isPendingtrue,可以用来显示加载指示器:

return isPending ? <div>Loading...</div> : <div>{someState}</div>;

代码示例

下面是一个完整的例子,展示如何使用 useTransition 优化搜索过滤场景:

import { useState, useTransition } from 'react';

function SearchList() {
  const [query, setQuery] = useState('');
  const [filteredList, setFilteredList] = useState([]);
  const [isPending, startTransition] = useTransition();

  // 模拟一个大数据列表
  const largeList = Array.from({ length: 10000 }, (_, i) => `Item ${i}`);

  const handleChange = (e) => {
    const value = e.target.value;
    setQuery(value); // 高优先级更新:输入框实时响应

    // 低优先级更新:过滤列表
    startTransition(() => {
      const filtered = largeList.filter(item => item.includes(value));
      setFilteredList(filtered);
    });
  };

  return (
    <div>
      <input
        type="text"
        value={query}
        onChange={handleChange}
        placeholder="Search..."
      />
      {isPending && <div>Filtering...</div>}
      <ul>
        {filteredList.slice(0, 100).map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

export default SearchList;

运行效果解释:

  • 输入时setQuery 是高优先级更新,输入框会立即反映用户输入。
  • 过滤时setFilteredList 被包裹在 startTransition 中,React 会延迟处理这个更新,避免阻塞输入。
  • 加载状态isPendingtrue 时显示“Filtering...”,提示用户过滤正在进行。

使用场景

  1. 大数据处理:比如过滤或排序大型列表时,避免界面卡顿。
  2. 复杂 UI 更新:如动态加载大量组件或计算密集型操作。
  3. 搜索或筛选功能:实时响应用户输入,同时延迟更新结果展示。

注意事项

  1. 不是所有更新都需要 useTransition
    只有当状态更新可能影响性能或用户体验时,才使用 startTransition。普通的小规模更新无需此优化。

  2. 与 Suspense 的关系
    useTransition 可以与 Suspense 配合使用。例如,在等待数据加载时,使用 startTransition 标记状态更新,结合 <Suspense> 显示 fallback。

  3. 浏览器支持
    useTransition 依赖 React 18 的并发特性,确保项目使用的是 React 18 及以上版本。


扩展示例:结合 Suspense

以下是一个结合 Suspense 的例子,模拟延迟加载数据:

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

function fetchData(query) {
  return new Promise(resolve => {
    setTimeout(() => resolve(`Result for ${query}`), 1000);
  });
}

function DataComponent({ resource }) {
  return <div>{resource}</div>;
}

function App() {
  const [query, setQuery] = useState('');
  const [resource, setResource] = useState(null);
  const [isPending, startTransition] = useTransition();

  const handleChange = (e) => {
    const value = e.target.value;
    setQuery(value);

    startTransition(() => {
      setResource(fetchData(value)); // 模拟异步数据获取
    });
  };

  return (
    <div>
      <input value={query} onChange={handleChange} />
      {isPending ? (
        <div>Loading...</div>
      ) : (
        <Suspense fallback={<div>Fetching...</div>}>
          {resource && <DataComponent resource={resource} />}
        </Suspense>
      )}
    </div>
  );
}

export default App;

效果:

  • 输入框实时更新。
  • 数据获取被标记为过渡状态,isPending 显示“Loading...”。
  • Suspense 的 fallback 在数据加载时显示“Fetching...”。

总结

useTransition 是 React 18 中用于优化性能的强大工具。通过将低优先级更新放入 startTransition,配合 isPending 提供反馈,可以显著提升应用的流畅度和用户体验。

posted on   joken1310  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Blazor Hybrid适配到HarmonyOS系统
· 支付宝 IoT 设备入门宝典(下)设备经营篇
· 万字调研——AI生成内容检测
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
点击右上角即可分享
微信分享提示