Suspense 组件内的多次使用调用会导致其他 Suspense 组件出现跨界渲染问题

问题描述 投票:0回答:1

当我在多个 Suspense 边界内使用 use 钩子时,我在 React 19 中遇到了一个问题,我有两个组件 和 ,它们的行为应该相似,但是当渲染包裹在 Suspense 中的项目时,它们表现出不同的渲染行为

在下面的代码中,我有两个组件,并且渲染项目列表,每个项目都包裹在 Suspense 边界中,这些项目应该根据提供给每个 Suspense 组件的等待时间以不同的时间间隔渲染

import { Suspense, use, useState } from "react";

const f = async (wait) => {
  await new Promise((resolve) => setTimeout(resolve, wait));
  return new Date();
};

const App = () => {
  const [open, setOpen] = useState(false);

  return (
    <>
      <Expected />
      <Unexpected />
    </>
  );
};

const Expected = () => {
  const [open, setOpen] = useState(false);

  return (
    <>
      <div>👍</div>
      <button onClick={() => setOpen(!open)}>{open ? "close" : "open"}</button>
      {open && <List wait={[1000, 2000, 3000, 4000, 5000]} />}
    </>
  );
};

const Unexpected = () => {
  const [open, setOpen] = useState(false);

  return (
    <>
      <div>🤔</div>
      <button onClick={() => setOpen(!open)}>{open ? "close" : "open"}</button>
      {open && <List wait={[1000, 2000, 3000, 3000, 5000]} />}
    </>
  );
};

const List = ({ wait }) => {
  const [t1] = useState(f(wait[0]));
  const [t2] = useState(f(wait[1]));
  const [t3] = useState(f(wait[2]));
  const [t4] = useState(f(wait[3]));
  const [t5] = useState(f(wait[4]));

  return (
    <>
      <Suspense fallback={<div>Loading No.1 ...</div>}>
        <Item time={t1} />
      </Suspense>
      <Suspense fallback={<div>Loading No.2 ...</div>}>
        <Item time={t2} />
      </Suspense>
      <Suspense fallback={<div>Loading No.3 ...</div>}>
        <Item time={t3} />
      </Suspense>
      <Suspense fallback={<div>Loading No.4 & No.5 ...</div>}>
        <Item time={t4} />
        <Item time={t5} />
      </Suspense>
    </>
  );
};

const Item = ({ time }) => {
  const t = use(time);

  console.log("render item");

  return <div>{t.toISOString()}</div>;
};

export default App;

两个组件 和 的行为方式应相同:项目 No.1 到 No.3 应间隔一秒显示,No.4 和 No.5 应一起显示,在 No.3 之后两秒

两个组件之间的行为不一致,在 中,本应单独显示的第 3 项被延迟,仅在第 4 号和第 5 号之后才显示,这破坏了预期的 Suspense 行为

我期望两个组件以相同的方式渲染它们的项目,每个 Suspense 边界独立处理其各自的项目,具体来说,我期望 1 号到 3 号以一秒的延迟顺序渲染,而 4 号和不管等待时间有多么微小的差别,No.5都会在五秒后一起出现

相反,在组件中,No.3 似乎被延迟了,并且仅在 No.4 和 No.5 之后渲染,即使它位于单独的 Suspense 边界中

这种行为是 React 19 中的错误吗?还是我错过了有关 Suspense 和 use 在这个版本中如何协同工作的内容?如何确保跨不同 Suspense 边界的一致行为?

reactjs react-hooks react-suspense react-19
1个回答
0
投票

use 钩子是实验性的,可能是您问题的原因。

以下是更好的方法:

const Item = ({ time }) => {
  const [t, setT] = useState(undefined);

  useEffect(() => {
    time.then((val) => setT(val));
  }, []);

 return <div>{t && t.toISOString()}</div>;
};
© www.soinside.com 2019 - 2024. All rights reserved.