SolidJSS
SolidJS8mo ago
4 replies
hannus

SolidStart SSR: Why does createAsync data work in JSX but not in a child component?

在 SolidStart



In a SolidStart project using SSR, I encountered an issue with a route component that uses createAsync to fetch an async resource. I’ve set deferStream: true, and here’s the problem:

When this route is rendered, some parts of the page correctly display the async data, but some parts (particularly in components) do not render the data properly until I manually refresh the page.

Here’s a simplified version of my component:
export const route = {
  preload() {
    getUserProfileQuery();
  },
} satisfies RouteDefinition;

export default function Profile() {
  const userProfile = createAsync(() => getUserProfileQuery(), {
    deferStream: true,
  });

  return (
    <div class="min-h-screen py-12 px-4 sm:px-6 lg:px-8">
      <p>{userProfile()?.data?.nickname}</p>
      <p>{userProfile()?.data?.date_of_birth?.toString()}</p>
      <p>{userProfile()?.data?.height_cm}</p>
      <p>{userProfile()?.data?.gender}</p>
      {/* The above JSX renders data correctly */}
      
      <NumberField
        step={0.1}
        defaultValue={userProfile()?.data?.height_cm}
      >
        <NumberFieldLabel>Height</NumberFieldLabel>
        <NumberFieldGroup>
          <NumberFieldInput name="height_cm" />
          <NumberFieldIncrementTrigger />
          <NumberFieldDecrementTrigger />
        </NumberFieldGroup>
      </NumberField>
      {/* This component doesn't work properly until I refresh the page */}
    </div>
  );
}

The NumberField component comes from solid-ui, which is built on top of Kobalte.

It seems like during client-side hydration, this component doesn’t wait for the async resource to resolve, even though the plain JSX above does. Why does the top part render correctly after the async resource resolves, but NumberField fails unless I refresh the page? Any idea how to ensure proper hydration or data availability across all components?
thanks
Was this page helpful?