ice icon indicating copy to clipboard operation
ice copied to clipboard

支持首 chunk 直出静态内容更加丰富的方案

Open answershuto opened this issue 8 months ago • 0 comments

Summary | 概述

No response

Motivation | 背景

假设有一个依赖服务端接口的组件。

function Box() {
  const data = useSuspenseData(getData);

  return (
    <div className={styles.box}>
      {
        data
      }
    </div>
  );
}

export default withSuspense(Box);

async function getData() {
  console.log('load box');

  await new Promise<any>((resolve) => {
    setTimeout(() => resolve(null), 1000);
  });

  return 'data';
}

外层使用时这样的,当我希望首 chunk 有内容时,我需要用 fallback 来指定静态内容

import styles from './index.module.css';
import Box from '@/components/Box/index';


export default function Home() {
  console.log('Render: Home');

  return (
    <div>
      <Box id="Box" fallback={<div className={styles.boxFallback} />} />
  </div>
  );
}

如果首 chunk 直出更多的内容,需要导出 Box 并作为 fullback,同时 Box 逻辑上需要支持无数据渲染(类似于传统的 CSR)

export {
  SuspenseBox: withSuspense(Box),
  Box,
}
export default function Home() {
  console.log('Render: Home');

  return (
    <div>
      <SuspenseBox id="Box" fallback={<Box />} />
  </div>
  );
}

Usage example | 使用示例

No response

Detailed design | 方案设计

考虑支持模式或者属性可以打开 fallback 到本身组件作为静态内容首次的渲染,fallback 为 boolean 值 true 的时候首 chunk 会渲染,提升首次渲染丰富度。

import styles from './index.module.css';
import Box from '@/components/Box/index';


export default function Home() {
  console.log('Render: Home');

  return (
    <div>
      <Box id="Box" fallback={true} />
  </div>
  );
}

Additional context | 额外信息

No response

answershuto avatar Oct 26 '23 04:10 answershuto