urql-graphql / urql

The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
https://urql.dev/goto/docs
MIT License
8.57k stars 444 forks source link

Infinite initialization? (with Graphql-codegen and Next.js 13) #3408

Closed shkim closed 8 months ago

shkim commented 9 months ago

Describe the bug

When I use the Provider for urql client, it seems that it is infinitely called when any query is activated.

I prepared the reproducible example code: https://github.com/shkim/urql-next13-error Remarkable files are:

src/app/GqlProvider.tsx src/app/layout.tsx src/app/query/page.tsx src/graphql/index.ts src/graphql/documents.tsx

src/graphql/generated.tsx file is generated with graphql-codegen it can be regenerated by "graphql-codegen --config gql-config.yml"

Thank you.

Reproduction

https://github.com/shkim/urql-next13-error

Urql version

@urql/next 1.1.0 (latest at the moment)

Validations

JoviDeCroock commented 9 months ago

That's because this line should be importing from @urql/next.

Changing your codegen file to be the one underneath should fix the issue at hand.

schema: https://swapi-graphql.netlify.app/.netlify/functions/index
generates:
  ./src/graphql/generated.ts:
    documents: ./src/graphql/documents.graphql
    config:
      urqlImportFrom: "@urql/next"
    plugins:
      - typescript
      - typescript-operations
      - typescript-urql

The second issue here is that you are missing Suspense boundaries, so during SSR it throws and never keeps the GqlProvider alive meaning the state is constantly renewed so changing your layout to be the following should be the second fix.

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import GqlProvider from "./GqlProvider";
import { Suspense } from "react";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <GqlProvider>
          <Suspense>
          {children}
          </Suspense>
        </GqlProvider>
      </body>
    </html>
  );
}
michaelzadra1 commented 8 months ago

I'm experiencing the same issue. I tried the above solution but it didn't resolve the problem.

Strangely enough, what resolves the infinite fetch problem for me is removing export const runtime = "edge"; from my Page components. There seems to be some issue with serving pages from edge fns w/ urql

JoviDeCroock commented 8 months ago

@michaelzadra1 That sounds like a different issue

JoviDeCroock commented 8 months ago

Going to close this issue out, feel free to create a new one for the edge issue! 🙌 will need an accompanying reproduction