前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >concurrent 模式 API 参考(实验版)

concurrent 模式 API 参考(实验版)

作者头像
Fonkie
修改2019-12-02 11:16:38
2.4K0
修改2019-12-02 11:16:38
举报
文章被收录于专栏:进击的全栈

注意:

本章节所描述的实验功能在稳定版本中尚不可用。请不要在应用程序的生产环境中依赖 React 的实验性版本。这些功能可能会发生重大变化,并且在成为 React 的一部分之前不会给出警告。

本文档面向早期此功能的使用者和对此功能好奇的人。如果你不熟悉 React,请不必担心 —— 你不需要立刻学习这些功能。

本章节为 concurrent 模式的 React API 参考。如果你想找导览,请查看 concurrent UI 模式。

注意:这是社区的预览版,并不是最终的稳定版本。这些 API 将来可能会发生变化。请自行承担风险!

启用 concurrent 模式 {#concurrent-mode}

createRoot {#createroot}

代码语言:txt
复制
ReactDOM.createRoot(rootNode).render(<App />);

替换 ReactDOM.render(<App />, rootNode) 并启用 concurrent 模式。

更多有关 concurrent 模式的信息,请查看 concurrent 模式文档

createBlockingRoot {#createblockingroot}

代码语言:txt
复制
ReactDOM.createBlockingRoot(rootNode).render(<App />)

替换 ReactDOM.render(<App />, rootNode) 并启用 blocking 模式。

选择 concurrent 模式会对 React 的工作方式带来语义上的变化。这意味着你不能只在一些组件中使用 concurrent 模式。因此,一些应用程序可能无法直接迁移到 concurrent 模式。

blocking 模式只包含了 concurrent 模式的小部分功能,它为无法直接迁移的应用程序提供了中间的迁移步骤。

Suspense API {#suspense}

Suspense {#suspensecomponent}

代码语言:txt
复制
<Suspense fallback={<h1>加载中...</h1>}>
  <ProfilePhoto />
  <ProfileDetails />
</Suspense>

Suspense 让你的组件在渲染之前进行“等待”,并在等待时显示 fallback 的内容。

在这个示例中,ProfileDetails 正在等待异步 API 调用来获取某些数据。在等待 ProfileDetailsProfilePhoto 时,我们将显示加载中...的 fallback。请注意,在 <Suspense> 中的所有子组件都加载之前,我们将继续显示这个 fallback。

Suspense 接受两个 props:

  • fallback 接受一个加载指示器。 这个 fallback 在 Suspense 所有子组件完成渲染之前将会一直显示。
  • unstable_avoidThisFallback 接受一个布尔值。它告诉 React 是否在初始加载时“跳过”显示这个边界,这个 API 可能会在以后的版本中删除。

<SuspenseList> {#suspenselist}

代码语言:txt
复制
<SuspenseList revealOrder="forwards">
  <Suspense fallback={'加载中...'}>
    <ProfilePicture id={1} />
  </Suspense>
  <Suspense fallback={'加载中...'}>
    <ProfilePicture id={2} />
  </Suspense>
  <Suspense fallback={'加载中...'}>
    <ProfilePicture id={3} />
  </Suspense>
  ...
</SuspenseList>

SuspenseList 通过编排向用户显示这些组件的顺序,来帮助协调许多可以挂起的组件。

当多个组件需要获取数据时,这些数据可能会以不可预知的顺序到达。不过,如果你将这些项目包装在 SuspenseList 中,React 将不会在列表中显示这个项目,直到它之前的项目已经显示(此行为可调整)。

SuspenseList 接受两个 props:

  • revealOrder (forwards, backwards, together) 定义了 SuspenseList 子组件应该显示的顺序。
    • together所有的子组件都准备好了的时候显示它们,而不是一个接着一个显示。
  • tail (collapsed, hidden) 指定如何显示 SuspenseList 中未加载的项目。
    • 默认情况下,SuspenseList 将显示列表中的所有 fallback。
    • collapsed 仅显示列表中下一个 fallback。
    • hidden 未加载的项目不显示任何信息。

请注意,SuspenseList 只对其下方最近的 SuspenseSuspenseList 组件进行操作。它不会搜索比一层更深的边界。不过,可以将多个 SuspenseList 组件相互嵌套来构建网格。

useTransition {#usetransition}

代码语言:txt
复制
const SUSPENSE_CONFIG = { timeoutMs: 2000 };

const [startTransition, isPending] = useTransition(SUSPENSE_CONFIG);

useTransition 允许组件在切换到下一个界面之前等待内容加载,从而避免不必要的加载状态。它还允许组件将速度较慢的数据获取更新推迟到随后渲染,以便能够立即渲染更重要的更新。

useTransition hook 返回两个值的数组。

  • startTransition 是一个接受回调的函数。我们用它来告诉 React 需要推迟的 state。
  • isPending 是一个布尔值。这是 React 通知我们是否正在等待过渡的完成的方式。

如果某个 state 更新导致组件挂起,则该 state 更新应包装在 transition 中

代码语言:txt
复制
const SUSPENSE_CONFIG = {timeoutMs: 2000 };

function App() {
  const [resource, setResource] = useState(initialResource);
  const [startTransition, isPending] = useTransition(SUSPENSE_CONFIG);
  return (
    <>
      <button
        disabled={isPending}
        onClick={() => {
          startTransition(() => {
            const nextUserId = getNextId(resource.userId);
            setResource(fetchProfileData(nextUserId));
          });
        }}
      >
        Next
      </button>
      {isPending ? " 加载中..." : null}
      <Suspense fallback={<Spinner />}>
        <ProfilePage resource={resource} />
      </Suspense>
    </>
  );
}

在这段代码中,我们使用 startTransition 包装了我们的数据获取。这使我们可以立即开始获取用户资料的数据,同时推迟下一个用户资料页面以及其关联的 Spinner 的渲染 2 秒钟(timeoutMs 中显示的时间)。

isPending 布尔值让 React 知道我们的组件正在切换,因此我们可以通过在之前的用户资料页面上显示一些加载文本来让用户知道这一点。

深入了解 transition,可以阅读 concurrent UI 模式.

useTransition 配置 {#usetransition-config}
代码语言:txt
复制
const SUSPENSE_CONFIG = { timeoutMs: 2000 };

useTransition 接受带有 timeoutMs可选的 Suspense 配置。 此超时(毫秒)告诉 React 在显示下一个状态(上例中为新的用户资料页面)之前等待多长时间。

注意:我们建议你在不同的模块之间共享 Suspense 配置。

useDeferredValue {#usedeferredvalue}

代码语言:txt
复制
const deferredValue = useDeferredValue(value, { timeoutMs: 2000 });

返回一个延迟的值,该值可能“延后”于最长的时间 timeoutMs

这通常用于在具有基于用户输入立即渲染的内容,以及需要等待数据获取的内容时,保持接口的可响应性。

文本输入框是个不错的例子。

代码语言:txt
复制
function App() {
  const [text, setText] = useState("hello");
  const deferredText = useDeferredValue(text, {timeoutMs: 2000 }); 

  return (
    <div className="App">
      {/* 保持将当前文本传递给 input */}
      <input value={text} onChange={handleChange} />
      ...
      {/* 但在必要时可以将列表“延后” */}
      <MySlowList text={deferredText} />
    </div>
  );
 }

这让我们可以立即显示 input 的新文本,从而感觉到网页的响应。同时,MySlowList “延后” 2 秒,根据 timeoutMs ,更新之前,允许它在后台渲染当前文本。

深入了解延迟值,可以阅读 concurrent UI 模式。

useDeferredValue 配置 {#usedeferredvalue-config}
代码语言:txt
复制
const SUSPENSE_CONFIG = { timeoutMs: 2000 };

useDeferredValue 接受带有 timeoutMs可选的 Suspense 配置。此超时(以毫秒为单位)表示延迟的值允许延后多长时间。

当网络和设备允许时,React 始终会尝试使用较短的延迟。

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 启用 concurrent 模式 {#concurrent-mode}
    • createRoot {#createroot}
      • createBlockingRoot {#createblockingroot}
      • Suspense API {#suspense}
        • Suspense {#suspensecomponent}
          • <SuspenseList> {#suspenselist}
            • useTransition {#usetransition}
              • useTransition 配置 {#usetransition-config}
            • useDeferredValue {#usedeferredvalue}
              • useDeferredValue 配置 {#usedeferredvalue-config}
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档