React Concurrent Mode(并发模式)

是什么

React Concurrent Mode(并发模式)是React 18中引入的一项新特性,旨在改进React的渲染方式,使其更具响应性和平滑性。在传统的React同步渲染模式中,组件的更新是同步执行的,如果某个组件的更新操作耗时较长,可能会导致用户界面的卡顿和响应性问题。而Concurrent Mode通过将任务拆分成小的、可中断的单元,并允许React在执行高优先级任务后,优雅地中断和恢复低优先级任务,从而实现更好的用户体验。

Concurrent Mode引入了一些措施来实现这一目标:

  1. 时间切片(Time Slicing):React将更新任务分成多个小的时间片(time slice),每个时间片执行的时间很短,一般为1毫秒。在每个时间片执行完后,React会检查是否还有剩余的时间片,如果有,则会优先执行其他高优先级任务,从而实现更平滑的用户界面。
  2. 任务优先级(Priorities):Concurrent Mode引入了不同优先级的任务。例如,用户输入相关的任务被认为是高优先级,而屏幕重新绘制等任务则是低优先级。React会根据任务的优先级来调度执行顺序,确保高优先级任务优先执行。
  3. 批量更新(Batching):在传统的同步渲染模式中,React会在每次状态更新后立即进行组件的重新渲染,而在Concurrent Mode中,React会将多个状态更新合并成一个批量更新,在一个时间片内一次性进行渲染,减少渲染的次数,提高渲染性能。
  4. Suspense组件:Suspense组件是Concurrent Mode中引入的新组件,用于优雅地处理异步数据获取和代码分割等情况。Suspense可以指定一个fallback(备用)组件,当异步操作尚未完成时,可以渲染fallback组件,提供更好的用户体验。

通过这些措施,React Concurrent Mode可以更好地处理复杂的界面更新和异步操作,提供更优秀的用户体验。需要注意的是,Concurrent Mode并不是强制使用的,可以根据项目的需求和性能要求来选择是否启用。

常用API

React Concurrent Mode引入了一些常用的API来支持并发渲染和异步操作。以下是React Concurrent Mode中常用的API:

  • Suspense 组件Suspense组件是Concurrent Mode中的新组件,用于优雅地处理异步数据获取和代码分割等情况。它可以指定一个fallback(备用)组件,在异步操作尚未完成时,渲染fallback组件,提供更好的用户体验。Suspense可以配合React.lazy()实现组件的代码分割,以及React.Suspense实现异步数据获取。
import React, { Suspense } from 'react';

const LazyComponent = React.lazy(() => import('./LazyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
}

  • React.lazy() 方法React.lazy()是一个动态导入(Dynamic Import)的方法,用于实现组件的代码分割。它允许将组件的导入延迟到组件实际被渲染的时候,从而减少初始加载时间,提高应用的性能。
import React, { lazy, Suspense } from 'react';

const LazyComponent = lazy(() => import('./LazyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
}

  • startTransition() 方法startTransition()是一个实验性的API,用于在Concurrent Mode中触发渲染的延迟。它可以接受一个回调函数,并将回调函数的执行延迟到下一个空闲时间。这个方法可以用来优化大型页面的渲染,以避免在繁忙的时间段阻塞渲染。
import React, { useState } from 'react';

function App() {
  const [isPending, setIsPending] = useState(false);

  const fetchData = async () => {
    setIsPending(true);
    // Simulate fetching data asynchronously
    await fetch('https://api.example.com/data');
    setIsPending(false);
  };

  const handleButtonClick = () => {
    // Start the transition to trigger deferred rendering
    startTransition(() => {
      fetchData();
    });
  };

  return (
    <div>
      <button onClick={handleButtonClick}>Fetch Data</button>
      {isPending && <div>Loading...</div>}
    </div>
  );
}

  • useTransition用于告知React开始一个优先级较低的异步更新。它返回一个数组,包含两个元素:第一个元素是布尔值isPending,表示当前的异步更新是否仍在进行中;第二个元素是一个函数startTransition,用于触发异步更新。
import React, { useState, useTransition } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);
  const [isPending, startTransition] = useTransition();

  const handleClick = () => {
    // 通过 startTransition 来触发异步更新
    startTransition(() => {
      setCount((prevCount) => prevCount + 1);
    });
  };

  return (
    <div>
      <p>Count: {count}</p>
      {isPending ? <p>Loading...</p> : null}
      <button onClick={handleClick}>Increment</button>
    </div>
  );
}

  • useDeferredValue用于获取一个被延迟处理的值。通过将某些值标记为被延迟处理,可以确保这些值在用户交互之后再进行更新,从而避免不必要的渲染。
import React, { useState, useDeferredValue } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);
  const deferredCount = useDeferredValue(count, { timeoutMs: 2000 });

  return (
    <div>
      <p>Count: {deferredCount}</p>
      <button onClick={() => setCount((prevCount) => prevCount + 1)}>
        Increment
      </button>
    </div>
  );
}

全部评论
大佬 我想问一下 他和fiber的关系与区别 求赐教
点赞 回复 分享
发布于 2023-12-23 11:21 上海

相关推荐

深夜书店vv:腾讯是这样的,去年很多走廊都加桌子当工区
点赞 评论 收藏
分享
评论
4
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务