Hi FE !
Ai
git
前端面试题
前端小tip
  • vite
  • webpack
npm
  • vue2
  • vue3
react
GitHub
Ai
git
前端面试题
前端小tip
  • vite
  • webpack
npm
  • vue2
  • vue3
react
GitHub
  • startTransition和useDeferredValue

startTransition和useDeferredValue

并发特性:

一、startTransition

在v18中运行如下代码:

import React, { useState, useEffect, useTransition } from 'react';

const App: React.FC = () => {
  const [list, setList] = useState<any[]>([]);
  const [isPending, startTransition] = useTransition();
  useEffect(() => {
    // 使用了并发特性,开启并发更新
    startTransition(() => {
      setList(new Array(10000).fill(null));
    });
  }, []);
  return (
    <>
      {list.map((_, i) => (
        <div key={i}>{i}</div>
      ))}
    </>
  );
};

export default App;

由于 setList 在 startTransition 的回调函数中执行(使用了并发特性),所以 setList 会触发并发更新。 startTransition,主要为了能在大量的任务下也能保持 UI 响应。这个新的 API 可以通过将特定更新标记为“过渡”来显著改善用户交互,简单来说,就是被 startTransition 回调包裹的 setState 触发的渲染被标记为不紧急渲染,这些渲染可能被其他紧急渲染所抢占。

有关startTransition的更多信息,请参阅 Patterns for startTransition。

二、useDeferredValue

返回一个延迟响应的值,可以让一个state 延迟生效,只有当前没有紧急更新时,该值才会变为最新值。useDeferredValue 和 startTransition 一样,都是标记了一次非紧急更新。 从介绍上来看 useDeferredValue 与 useTransition 是否感觉很相似呢?

相同:useDeferredValue 本质上和内部实现与 useTransition 一样,都是标记成了延迟更新任务。 不同:useTransition 是把更新任务变成了延迟更新任务,而 useDeferredValue 是产生一个新的值,这个值作为延时状态。(一个用来包装方法,一个用来包装值)

所以,上面 startTransition 的例子,我们也可以用 useDeferredValue 来实现:

import React, { useState, useEffect, useDeferredValue } from 'react';

const App: React.FC = () => {
  const [list, setList] = useState<any[]>([]);
  useEffect(() => {
    setList(new Array(10000).fill(null));
  }, []);
  // 使用了并发特性,开启并发更新
  const deferredList = useDeferredValue(list);
  return (
    <>
      {deferredList.map((_, i) => (
        <div key={i}>{i}</div>
      ))}
    </>
  );
};

export default App;

然后启动项目,查看一下打印的执行堆栈图:

此时我们的任务被拆分到每一帧不同的 task 中,JS脚本执行时间大体在5ms左右,这样浏览器就有剩余时间执行样式布局和样式绘制,减少掉帧的可能性。

有关useDeferredValue的更多信息,请参阅 New in 18: useDeferredValue。

三、普通情况 我们可以关闭并发特性,在普通环境中运行项目:

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

const App: React.FC = () => {
  const [list, setList] = useState<any[]>([]);
  useEffect(() => {
    setList(new Array(10000).fill(null));
  }, []);
  return (
    <>
      {list.map((_, i) => (
        <div key={i}>{i}</div>
      ))}
    </>
  );
};

export default App;
Edit this page
最近更新: 2025/6/27 02:24
Contributors: qdleader
qdleader
本站总访问量 129823次 | 本站访客数 12人