You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Suspense与use结合时React子组件重复渲染?

解决React组件重复渲染导致Promise重复创建的问题

你的问题核心是:父组件App的状态更新触发重渲染时,FirstChild随之重新执行并创建新的Promise,导致Suspense再次进入加载状态。按照React“同位置组件保留状态”的规则,可以通过以下两种方式解决:

方案一:用useMemo缓存Promise实例

通过useMemo将Promise的创建逻辑缓存起来,确保组件重渲染时复用同一个Promise,避免重复触发Suspense挂起。

修改后的代码:

import { Suspense, use, useState, useMemo } from 'react'

function FirstChild({ setSecondContent }) {
  // 用useMemo缓存Promise,仅在依赖项变化时重新创建
  const promise = useMemo(() => new Promise(resolve => {
    setTimeout(() => {
      setSecondContent('More content...');
      resolve('Done!');
    }, 3000);
  }), [setSecondContent]); // useState返回的setter引用稳定,不会触发重新创建

  return (
    <Suspense fallback={<>{'Loading...'}<br/></>}>
      <FirstChildContent contentPromise={promise} />
    </Suspense>
  );
}

function FirstChildContent({ contentPromise }) {
  const content = use(contentPromise);
  return <>{content}<br/></>;
}

function SecondChild({ content }) {
  return content;
}

export default function App() {
  const [secondContent, setSecondContent] = useState('');
  return (
    <>
      <FirstChild setSecondContent={setSecondContent} />
      { secondContent !== '' && <SecondChild content={secondContent} /> }
    </>
  );
}

方案二:用React.memo避免不必要的重渲染

React.memo会对组件的props做浅比较,当props未发生变化时,跳过组件的重渲染,从根源上避免Promise重复创建。

修改后的代码:

import { Suspense, use, useState, memo } from 'react'

// 用memo包裹FirstChild,props未变化时不触发重渲染
const FirstChild = memo(function({ setSecondContent }) {
  const promise = new Promise(resolve => {
    setTimeout(() => {
      setSecondContent('More content...');
      resolve('Done!');
    }, 3000);
  });
  return (
    <Suspense fallback={<>{'Loading...'}<br/></>}>
      <FirstChildContent contentPromise={promise} />
    </Suspense>
  );
});

function FirstChildContent({ contentPromise }) {
  const content = use(contentPromise);
  return <>{content}<br/></>;
}

function SecondChild({ content }) {
  return content;
}

export default function App() {
  const [secondContent, setSecondContent] = useState('');
  return (
    <>
      <FirstChild setSecondContent={setSecondContent} />
      { secondContent !== '' && <SecondChild content={secondContent} /> }
    </>
  );
}

核心逻辑说明

两种方案本质都是遵循React“同位置组件保留状态”的规则:

  • 方案一通过缓存Promise,让组件重渲染时复用原有异步资源,避免重复挂起;
  • 方案二通过阻止不必要的重渲染,确保Promise只在组件初次挂载时创建一次。

内容的提问来源于stack exchange,提问作者pdacostaporto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:27:05