React18中startTransition与useTransition的使用

 更新时间:2025年05月20日 10:52:50   作者:jnsytgsyqjgm  
本文主要介绍了React18中startTransition与useTransition的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

React 18 引入了多项令人兴奋的新特性,其中 startTransition 和 useTransition 是并发模式(Concurrent Mode)中的关键部分,旨在提升用户体验,通过区分紧急和非紧急任务来优化应用的响应性。本文将详细介绍这两个特性及其在实际开发中的应用。

一、并发模式与任务优先级

在 React 18 之前,所有的状态更新都是同步处理的,这意味着一旦状态改变,组件就会立即重新渲染。这可能导致在处理大量数据或复杂视图时,界面出现卡顿现象,影响用户体验。

并发模式的引入,使得 React 能够以不同的优先级处理状态更新,从而保持界面的流畅性。紧急任务(如用户输入、点击等)会被立即处理,而非紧急任务(如数据过滤、分页切换等)则会被延迟处理。

React 18 引入的 startTransition 和 useTransition 旨在解决这类问题。它们允许开发者将一些非关键的状态更新标记为过渡性更新,从而将其优先级降低,让 React 在主线程空闲时再去处理这些更新,确保关键的用户交互(如点击、滚动、输入等)能够得到及时响应,使应用始终保持流畅和可用。

二、startTransition 的使用

(一)基本语法与用法

startTransition 是一个 API,用于标记某些状态更新为非紧急任务。它允许开发者在不影响用户交互的情况下,延迟处理一些低优先级的更新。

import React, { useState, startTransition } from 'react';

const App = () => {
  // 用于存储输入框数据的状态
  const [inputValue, setInputValue] = useState('');
  // 用于存储处理后数据的状态
  const [processedData, setProcessedData] = useState('');

  const handleInputChange = (e) => {
    const newData = e.target.value;
    setInputValue(newData);
    startTransition(() => {
      // 这里模拟对输入数据进行一些耗时处理,比如拼接一个长字符串
      const processed = newData + ', processed and modified. This is a long text to simulate a heavy operation. '.repeat(1000);
      setProcessedData(processed);
    });
  };

  return (
    <div>
      <input type="text" onChange={handleInputChange} placeholder="Enter something" />
      <p>Input: {inputValue}</p>
      <p>Processed Data: {processedData}</p>
    </div>
  );
};

export default App;

在这个示例中,当用户在输入框中输入内容时,inputValue 会立即更新以反映用户输入。同时,startTransition 会将对 processedData 的更新操作标记为过渡性更新。这意味着,即使处理 processedData 的过程可能比较耗时(如模拟的长字符串拼接),用户界面在这个过程中仍然可以响应其他操作,比如继续输入文本,而不会出现卡顿现象,直到主线程有空闲时间来处理 processedData 的更新并在界面上显示最终结果。

(二)内部工作原理

当 startTransition 被调用时,React 会将传入的更新函数放入一个低优先级的任务队列中。它会首先处理完当前正在进行的高优先级任务(如用户的即时交互操作对应的更新),然后在主线程有空闲时间时,才会从低优先级任务队列中取出这些过渡性更新任务并执行。这样就有效地避免了因大量数据更新或复杂计算导致的界面卡顿,使得应用在更新过程中依然能够响应用户的其他操作。

三、useTransition 的使用

(一)基本语法与返回值

useTransition 是一个 React Hook,它在函数组件中使用。其语法如下:

import { useTransition } from'react';
const [isPending, startTransition] = useTransition();

它返回一个包含两个元素的数组。第一个元素 isPending 是一个布尔值,表示当前是否有过渡性更新正在进行。第二个元素 startTransition 与前面提到的全局 startTransition 函数功能相同,用于标记状态更新为过渡性更新。

(二)在组件中的应用示例

以下是一个更完整的示例,展示了 useTransition 在一个搜索组件中的应用:

import React, { useState, useTransition } from "react";
import { Input, Spin, List } from "antd";

const { Search } = Input;

// 生成 1000 条模拟数据
const mockData = [];
for (let i = 1; i <= 1000; i++) {
  mockData.push({
    id: i,
    name: `Item ${i}`,
    description: `This is the description of item ${i}`
  });
}

const App = () => {
  // 搜索关键词状态
  const [searchQuery, setSearchQuery] = useState("");
  // 搜索结果状态
  const [searchResults, setSearchResults] = useState(mockData);
  // 通过 useTransition 获取 startTransition 和 isPending
  const [isPending, startTransition] = useTransition();

  const handleSearch = (value) => {
    setSearchQuery(value);
    startTransition(() => {
      // 模拟异步搜索操作
      const newResults = mockData.filter((item) =>
        item.name.toLowerCase().includes(value.toLowerCase())
      );
      setSearchResults(newResults);
    });
  };

  return (
    <div>
      <Search
        placeholder="Search..."
        onChange={(e) => handleSearch(e.target.value)}
        enterButton
      />
      {isPending && (
        <Spin
          style={{
            marginTop: 16,
            textAlign: "center"
          }}
        />
      )}
      <List
        bordered
        dataSource={searchResults}
        renderItem={(item) => (
          <List.Item key={item.id}>
            <List.Item.Meta
              title={item.name}
              description={item.description}
            />
          </List.Item>
        )}
      />
    </div>
  );
};

export default App;

在上述代码中,当用户在搜索框中输入内容并执行搜索时,会在模拟的异步搜索操作中过滤数据,并根据 useTransition 的状态显示 Spin 加载组件或搜索结果列表。这样在搜索大数据量时,能够利用 useTransition 来优化用户体验,避免界面卡顿。

四、应用场景

startTransition 和 useTransition 非常适合用于以下场景:

  • 搜索和过滤:当用户输入关键词进行搜索或过滤时,可以立即更新输入框的值,并延迟更新搜索结果。
  • 复杂视图:在处理包含大量数据的复杂视图时,可以使用 startTransition 延迟更新,以保持界面的流畅性。
  • 分页切换:在分页切换时,可以立即更新页码,并延迟加载新页面的数据。

五、避免过度使用与性能平衡

虽然 startTransition 和 useTransition 能够有效提升用户体验,但也不能过度依赖。过多的过渡性更新可能会导致低优先级任务队列积压,最终影响整体性能。在设计应用时,需要合理评估哪些状态更新是真正适合标记为过渡性的,并且结合其他性能优化策略,如数据分页、缓存机制、虚拟列表等,以达到最佳的性能平衡。

到此这篇关于React18中startTransition与useTransition的使用的文章就介绍到这了,更多相关React18 startTransition useTransition内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • react组件传值的四种方法

    react组件传值的四种方法

    本文主要介绍了react组件传值的四种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • React 脚手架配置代理完整指南(最新推荐)

    React 脚手架配置代理完整指南(最新推荐)

    本文详细介绍了React脚手架配置代理的多种方式,文章还讨论了常见问题的解决方案,如跨域问题、WebSocket代理和错误处理,并提供了生产环境配置建议和调试技巧,感兴趣的朋友一起看看吧
    2024-12-12
  • React hooks中useState踩坑之异步的问题

    React hooks中useState踩坑之异步的问题

    这篇文章主要介绍了React hooks中useState踩坑之异步的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • 详解React中函数式组件与类组件的不同

    详解React中函数式组件与类组件的不同

    React 函数式组件与类组件的主要区别在于它们的定义和声明方式以及它们之间的一些特性,所以本文就详细的给大家讲讲React中函数式组件与类组件有何不同,需要的朋友可以参考下
    2023-09-09
  • react项目打包后点击index.html页面出现空白的问题

    react项目打包后点击index.html页面出现空白的问题

    这篇文章主要介绍了react项目打包后点击index.html页面出现空白的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • react配置代理setupProxy.js无法访问v3.0版本问题

    react配置代理setupProxy.js无法访问v3.0版本问题

    这篇文章主要介绍了react配置代理setupProxy.js无法访问v3.0版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • React手写redux过程分步讲解

    React手写redux过程分步讲解

    这篇文章主要介绍了React手写redux过程,目前redux在react中使用是最多的,所以我们需要将之前编写的redux代码,融入到react当中去,本文给大家详细讲解,需要的朋友可以参考下
    2022-12-12
  • React通过ref获取子组件的数据和方法

    React通过ref获取子组件的数据和方法

    这篇文章主要介绍了React如何通过ref获取子组件的数据和方法,文中有详细的总结内容和代码示例,具有一定的参考价值,需要的朋友可以参考下
    2023-10-10
  • react build 后打包发布总结

    react build 后打包发布总结

    这篇文章主要介绍了react build 后打包发布总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 如何对react hooks进行单元测试的方法

    如何对react hooks进行单元测试的方法

    这篇文章主要介绍了如何对react hooks进行单元测试的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08

最新评论