apollographql / apollo-client-nextjs

Apollo Client support for the Next.js App Router
https://www.npmjs.com/package/@apollo/experimental-nextjs-app-support
MIT License
358 stars 25 forks source link

Using useSuspenseQuery is client side supposed to send a request on the first render? #106

Closed Stevemoretz closed 7 months ago

Stevemoretz commented 7 months ago

I'm using useSuspenseQuery and it's working fine I get the result from the server, I don't understand why it again send a query on the same initial render from the client side, is that supposed to happen or did I miss something?

phryneas commented 7 months ago

Are you using useSuspenseQuery from @apollo/client or @apollo/experimental-nextjs-app-support? That's the most common cause for this behaviour - you need to use the latter, as we need to wrap the first in some additional logic to make everything work.

Stevemoretz commented 7 months ago

Are you using useSuspenseQuery from @apollo/client or @apollo/experimental-nextjs-app-support? That's the most common cause for this behaviour - you need to use the latter, as we need to wrap the first in some additional logic to make everything work.

Thanks for the reply I am using @apollo/experimental-nextjs-app-support first request is running on both server and client, using:

"next": "13.5.3"
"@apollo/client": "3.9.0-alpha.1",
"@apollo/experimental-nextjs-app-support": "0.4.3",
Stevemoretz commented 7 months ago

Using @apollo/client although it still runs on both client and server, server shows undefined as data, using @apollo/experimental-nextjs-app-support I get the response on both client and server, but don't understand why client needs to get it again.

phryneas commented 7 months ago

Thanks for the reply I am using @apollo/experimental-nextjs-app-support first request is running on both server and client, using:

No, how are you importing useSuspenseQuery in your source code?

Please give a code example on how you use this, including the imports.

Stevemoretz commented 7 months ago

Thanks for the reply I am using @apollo/experimental-nextjs-app-support first request is running on both server and client, using:

No, how are you importing useSuspenseQuery in your source code?

Please give a code example on how you use this, including the imports.

Sure! Thanks.

My page.tsx:

"use client";

import {gql} from "@apollo/client";
import {useSuspenseQuery} from "@apollo/experimental-nextjs-app-support/ssr";
import SpinnerBase from "@src/app/components/Spinner/SpinnerBase";
import {Suspense} from "react";

type Props = {};

export function Shop(props: Props) {
    const {data, error} = useSuspenseQuery(
        gql`
            query ($page: Int, $search: String) {
                boxes(
                    first: 1
                    page: $page
                    filters: {search: $search}
                    orderBy: [
                        {
                            freeSlots: {aggregate: COUNT, column: REGULAR_PRICE}
                            order: ASC
                        }
                    ]
                ) {
                    data {
                        id
                    }
                }
            }
        `,
        {
            variables: {
                page: 1,
                search: "U",
            },
            fetchPolicy: "no-cache",
        },
    );
    if (error) {
        // we want not only the initial error to throw towards a suspense boundary,
        // but also errors coming in later to trigger the same boundary
        throw error;
    }
    console.log(data);

    return null;
}

export default function Component(props: Props) {
    return (
        <Suspense fallback={<SpinnerBase />}>
            <Shop {...props} />
        </Suspense>
    );
}
phryneas commented 7 months ago

It's the fetchPolicy: "no-cache". While it does render on the server and also transports the result of that over to the client cache, you explicitly tell it that it shouldn't be using that transported value - so it has to do another request.

Stevemoretz commented 7 months ago

It's the fetchPolicy: "no-cache". While it does render on the server and also transports the result of that over to the client cache, you explicitly tell it that it shouldn't be using that transported value - so it has to do another request.

Thanks a lot! Couldn't figure this out without your help!