useQuery oncomplete during SSR

Hi

I have an application using apollo and zustand. It is an isomorphic app thats support full SSR and then client hydration.

I’m attempting to use useQuery 's onComplete callback to update my zustand state.

This works on the client but on the server it looks like it renders before the oncomplete callback has run. So I get a server render that is missing the data from api.

example

 useQuery(
    QUERY,
    {
      fetchPolicy: 'cache-first',
      nextFetchPolicy: 'cache-and-network',
      variables,
      onCompleted: (data) => {
        // zustand store action - update results in store
        updateResults(data.results);
      },
    }
  );

Is this expected functionality?

It kinda is - onCompleted has always been triggered after the hook’s internal state update - but React decides on it’s own when to actually rerender. React 17 would immediately rerender, React 18 will batch rerenders, so your onComplete will actually run before (not sure if you get the same behaviour in SSR though).

That said, I believe this workflow will generally be problematic - do you have a way of transporting that Zustand state to the browser and hydrating it there before your component renders? Otherwise you’ll end up with a hydration mismatch.

Generally we do not recommend copying Apollo Client state into other state managers - Apollo Client is already an async state manager. You just make things a lot more complicated for yourself.

@lenz - thanks for the info

Yes we can transport the state to the browser and hydrate.

Our challenge is we operate in a micro frontend architecture with a shared apollo client instance. The data we get we merge with data from multiple queries and transform before placing it in state. So it can look different to what is in the client.

We are restricted as we can’t alter the shared client too much, e.g. we can’t do things to the apollo client like add field policies to handle some of this. :frowning_face:

This might depend on your internal rules, but technically you can use addTypePolicies to add new type policies to an existing cache: Configuring the Apollo Client cache