solid-start icon indicating copy to clipboard operation
solid-start copied to clipboard

[Bug?]: clientOnly inside Suspense boundary with createAsync that uses server action and cache is not rendered

Open nirtamir2 opened this issue 1 year ago • 1 comments

Duplicates

  • [X] I have searched the existing issues

Latest version

  • [X] I have tested the latest version

Current behavior 😯

I added a stackblitz - it works there but on local env it won't work (and also not on a server). It seems like we need to co-locate cache and use-server functions to the same file and we cannot split them. When I declare my cache in a different file - it does not render clientOnly component.

https://stackblitz.com/edit/github-grada5-rgyttr?file=src%2Froutes%2Fabout.tsx

I'm using SolidStart and I'm trying to render component based on createAsync result. This component is wrapped with clientOnly - because it depends in the DOM. It did not render this component. Here is a small reproduction

server.ts

export const getData = cache(async () => {
  "use server";
  return Promise.resolve(55);
}, "tierlists");


import {getData} from "./server"
import Test from "./Test";

const TestClientOnly = clientOnly(() => import("./Test"));

export function MyComponent() {
  const a = createAsync(async () => {
    return { data: await getData() };
  });
  return (
    <Suspense>
      <Show when={a()} fallback={<div>Loading tierlist</div>}>
        {/*  This will not render anything ⚠️ only the fallback */}
        {(a) => <TestClientOnly fallback={"Fallback why?"}/>}
        {/*  This will render Test ✅*/}
        {(a) => <Test />}
      </Show>
    </Suspense>
  );

And inside ./Test.tsx

export default function Test(){
    return <div>Test</div>;
}

The result is that the TestClientOnly component does not rendered anything and goes into the fallback (if provided) to "Fallback why"

Expected behavior 🤔

The component will be shown and render (same as <Test/>)

Steps to reproduce 🕹

import Test from "./Test";

const TestClientOnly = clientOnly(() => import("./Test"));

export function MyComponent() {
  const a = createAsync(async () => {
    return { data: await getData() };
  });
  return (
    <Suspense>
      <Show when={a()} fallback={<div>Loading tierlist</div>}>
        {/*  This will not render anything ⚠️ only the fallback */}
        {(a) => <TestClientOnly fallback={"Fallback why?"}/>}
        {/*  This will render Test ✅*/}
        {(a) => <Test />}
      </Show>
    </Suspense>
  );

And inside ./Test.tsx

export default function Test(){
    return <div>Test</div>;
}

Context 🔦

I'm trying to use clientOnly component with data that comes from createAsync. It did not render the component - and it uses the fallback. But as I moved the cache and use server to a function in the same file - it did render.

Your environment 🌎

MacOS M1 Max, Node 22, pnpm, latest deps

nirtamir2 avatar Nov 07 '24 02:11 nirtamir2