DEV Community

Cover image for We Tried Recursive React Server Components + Suspense - It Just Worked
Matthew Wang
Matthew Wang

Posted on

We Tried Recursive React Server Components + Suspense - It Just Worked

Tried recursive React components with Server Components + Suspense fully expecting the universe to implode. It just… worked.

Live demo + minimal pattern here

Full Code:


const RATIO = 1 / 1.61803398875;

async function Box(props: {
  placement: "top" | "bottom" | "left" | "right";
  depth: number;
}) {
  if (props.depth > 10) {
    return null;
  }
  await new Promise((resolve) => setTimeout(resolve, 1000));
  return (
    <div
      style={{
        width: `${100 * RATIO}%`,
        ...{
          top: {
            top: 0,
            left: 0,
            transform: "translateY(-100%)",
          },
          right: {
            top: 0,
            right: 0,
            transform: "translateX(100%)",
          },
          bottom: {
            bottom: 0,
            right: 0,
            transform: "translateY(100%)",
          },
          left: {
            bottom: 0,
            left: 0,
            transform: "translateX(-100%)",
          },
        }[props.placement],
      }}
      className="absolute outline outline-white/50 border-white animate-fade-in aspect-square"
    >
      <Suspense fallback={null}>
        <Box
          placement={
            (
              {
                top: "right",
                right: "bottom",
                bottom: "left",
                left: "top",
              } as const
            )[props.placement]
          }
          depth={props.depth + 1}
        />
      </Suspense>
      <div className="absolute inset-0 border border-white text-white overflow-clip">
        <Circle placement={props.placement} />
      </div>
    </div>
  );
}

function Circle(props: { placement: "top" | "bottom" | "left" | "right" }) {
  return (
    <div
      className="rounded-full border border-white absolute overflow-clip aspect-square"
      style={{
        width: `200%`,
        ...{
          top: {
            right: 0,
            bottom: 0,
            transform: "translate(50%, 50%)",
          },
          right: {
            left: 0,
            bottom: 0,
            transform: "translate(-50%, 50%)",
          },
          bottom: {
            left: 0,
            top: 0,
            transform: "translate(-50%, -50%)",
          },
          left: {
            right: 0,
            top: 0,
            transform: "translate(50%, -50%)",
          },
        }[props.placement],
      }}
    >
      <div className="absolute inset-0 animate-flash bg-white/50 opacity-20" />
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)