SimeonGriggs / sanity-react-router-template

Sanity Studio v3 embedded into a Remix Vite application configured for Vercel hosting with visual editing
https://sanity-remix-template.sanity.build
164 stars 35 forks source link

loadQuery with streaming #68

Closed dvnrsn closed 6 months ago

dvnrsn commented 6 months ago

Because of the complexity of some of my queries I've taken to relying on stream and defer. However, I am not sure if this is going to be compatible with the new loadQuery which returns an "initial" that needs to be consumed by the useQuery hook.

  const moduleData = context.sanity.loadQuery
  return defer({ moduleData
const {data} = useLoaderData()

return <Suspense>
  <Await reolve={data}

Is streaming compatible with Visual Editing?

SimeonGriggs commented 6 months ago

I've not tried it – could you just pass initial into your component and run useQuery() inside it?

dvnrsn commented 6 months ago

Probably not because useQuery doesn't know what to do with a promise.


export async function loader({context, params}: LoaderFunctionArgs) {
  // notice there is no await here, because with streaming we want the promise
  const initial =
    context.sanity.loadQuery<SanityHomePage>(QUERY);
  return defer({
    initial,
    query: QUERY,
  });
}

export default function Index() {
  const {initial, query} = useLoaderData<typeof loader>();
  const {data, loading} = useQuery(query, undefined, initial);
  // error Property 'initial' is missing in type 'Promise<JsonifyObject<QueryResponseInitial<SanityHomePage>>>' 
  // but required in type 'UseQueryOptionsDefinedInitial<unknown>'

Perhaps we exclude the "initial" value from useQuery() but now we've lost the advantage of SSR. It seems recommended to use useQuery anyhow

SimeonGriggs commented 6 months ago

Ah. It should work but you'll need to move the useQuery hook into the awaited component.