Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react integration: using ReactQueryDevtools inside RSPCProvider #107

Open
Tracked by #269
dlight opened this issue Jan 8, 2023 · 7 comments
Open
Tracked by #269

react integration: using ReactQueryDevtools inside RSPCProvider #107

dlight opened this issue Jan 8, 2023 · 7 comments
Labels
v1.x A change for version 1.x.x

Comments

@dlight
Copy link

dlight commented Jan 8, 2023

Apologies if this is already fixed on master, I'm on @rspc/react 0.1.2 (and @tanstack/react-query 4.21.0, @tanstack/react-query-devtools 4.21.0)

So, react-query has a devtools widget that looks like this:

<QueryClientProvider client={queryClient}>
  {/* The rest of your application */}
  <ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>

Since `RSPCProvider is defined as

<Context.Provider
      value={{
        client,
        queryClient,
      }}
    >
      <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</Context.Provider>

I expected that I could just add a `ReactQueryDevtools tag inside it, like this

<RSPCProvider client={client} queryClient={queryClient}>
    <ReactQueryDevtools initialIsOpen={true} />
</RSPCProvider>

But this is met with an inescrutable error

See error message
error - [rendering] [root of the dev server]/  Error during SSR Rendering
  TypeError: __TURBOPACK__imported__module__$5b$project$2d$with$2d$next$5d2f$node_modules$2f2e$pnpm$2f$next$40$13$2e$1$2e$1_biqbaboplfbrettd7655fr4n2y$2f$node_modules$2f$next$2f$dist$2f$compiled$2f$react$2f$react$2e$shared$2d$subset$2e$js__.createContext is not a function
    at <unknown> (/node_modules/.pnpm/@tanstack+react-query@4.21.0_biqbaboplfbrettd7655fr4n2y/node_modules/@tanstack/react-query/build/lib/QueryClientProvider.mjs:3:43) [<unknown> (.next/server/app/chunks/rsc/_87ae68.js:7003:252)]
    at Module.[project-with-next]/node_modules/.pnpm/@tanstack+react-query@4.21.0_biqbaboplfbrettd7655fr4n2y/node_modules/@tanstack/react-query/build/lib/QueryClientProvider.mjs (ecmascript, rsc) (.next/server/app/chunks/rsc/_87ae68.js:7045:3)
    at <unknown> (.next/server/app/chunks/ssr/_790a59.js:68959:21)
    at runModuleExecutionHooks (.next/server/app/chunks/ssr/_790a59.js:68998:5)
    at instantiateModule (.next/server/app/chunks/ssr/_790a59.js:68958:5)
    at getOrInstantiateModuleFromParent (.next/server/app/chunks/ssr/_790a59.js:69040:12)
    at esmImport (.next/server/app/chunks/ssr/_790a59.js:68769:20)
    at <unknown> (.next/server/app/chunks/rsc/_87ae68.js:6895:265)
    at Module.[project-with-next]/node_modules/.pnpm/@tanstack+react-query@4.21.0_biqbaboplfbrettd7655fr4n2y/node_modules/@tanstack/react-query/build/lib/useQueries.mjs (ecmascript, rsc) (.next/server/app/chunks/rsc/_87ae68.js:6975:3)
    at <unknown> (.next/server/app/chunks/ssr/_790a59.js:68959:21)
    at runModuleExecutionHooks (.next/server/app/chunks/ssr/_790a59.js:68998:5)
    at instantiateModule (.next/server/app/chunks/ssr/_790a59.js:68958:5)
    at getOrInstantiateModuleFromParent (.next/server/app/chunks/ssr/_790a59.js:69040:12)
    at esmImport (.next/server/app/chunks/ssr/_790a59.js:68769:20)
    at <unknown> (.next/server/app/chunks/rsc/_87ae68.js:6852:256)
    at Module.[project-with-next]/node_modules/.pnpm/@tanstack+react-query@4.21.0_biqbaboplfbrettd7655fr4n2y/node_modules/@tanstack/react-query/build/lib/index.mjs (ecmascript, rsc) (.next/server/app/chunks/rsc/_87ae68.js:6876:3)
    at <unknown> (.next/server/app/chunks/ssr/_790a59.js:68959:21)
    at runModuleExecutionHooks (.next/server/app/chunks/ssr/_790a59.js:68998:5)
    at instantiateModule (.next/server/app/chunks/ssr/_790a59.js:68958:5)
    at getOrInstantiateModuleFromParent (.next/server/app/chunks/ssr/_790a59.js:69040:12)
    at esmImport (.next/server/app/chunks/ssr/_790a59.js:68769:20)
    at <unknown> (.next/server/app/chunks/rsc/_87ae68.js:250:251)
    at Module.[project-with-next]/node_modules/.pnpm/@tanstack+react-query-devtools@4.21.0_67mjlkwmhckybkh7pbuxjzh4me/node_modules/@tanstack/react-query-devtools/build/lib/devtools.mjs (ecmascript, rsc) (.next/server/app/chunks/rsc/_87ae68.js:988:3)
    at <unknown> (.next/server/app/chunks/ssr/_790a59.js:68959:21)
    at runModuleExecutionHooks (.next/server/app/chunks/ssr/_790a59.js:68998:5)
    at instantiateModule (.next/server/app/chunks/ssr/_790a59.js:68958:5)
    at getOrInstantiateModuleFromParent (.next/server/app/chunks/ssr/_790a59.js:69040:12)
    at esmImport (.next/server/app/chunks/ssr/_790a59.js:68769:20)
    at <unknown> (.next/server/app/chunks/rsc/_87ae68.js:230:278)
    at Module.[project-with-next]/node_modules/.pnpm/@tanstack+react-query-devtools@4.21.0_67mjlkwmhckybkh7pbuxjzh4me/node_modules/@tanstack/react-query-devtools/build/lib/index.mjs (ecmascript, rsc) (.next/server/app/chunks/rsc/_87ae68.js:241:3)
    at <unknown> (.next/server/app/chunks/ssr/_790a59.js:68959:21)
    at runModuleExecutionHooks (.next/server/app/chunks/ssr/_790a59.js:68998:5)
    at instantiateModule (.next/server/app/chunks/ssr/_790a59.js:68958:5)
    at getOrInstantiateModuleFromParent (.next/server/app/chunks/ssr/_790a59.js:69040:12)
    at esmImport (.next/server/app/chunks/ssr/_790a59.js:68769:20)
    at <unknown> (.next/server/app/chunks/rsc/_87ae68.js:10:275)
    at Module.[project-with-next]/app/page.tsx (ecmascript, rsc) (.next/server/app/chunks/rsc/_87ae68.js:43:3)
    at <unknown> (.next/server/app/chunks/ssr/_790a59.js:68959:21)
    at runModuleExecutionHooks (.next/server/app/chunks/ssr/_790a59.js:68998:5)
    at instantiateModule (.next/server/app/chunks/ssr/_790a59.js:68958:5)
    at getOrInstantiateModuleFromParent (.next/server/app/chunks/ssr/_790a59.js:69040:12)
    at esmImport (.next/server/app/chunks/ssr/_790a59.js:68769:20)
    at <unknown> (.next/server/app/chunks/rsc/_87ae68.js:113:92)
    at Module.[project-with-next]/app/page.tsx/layout-entry.tsx (ecmascript, rsc) (.next/server/app/chunks/rsc/_87ae68.js:126:3)
    at <unknown> (.next/server/app/chunks/ssr/_790a59.js:68959:21)
    at runModuleExecutionHooks (.next/server/app/chunks/ssr/_790a59.js:68998:5)
    at instantiateModule (.next/server/app/chunks/ssr/_790a59.js:68958:5)
    at getOrInstantiateModuleFromParent (.next/server/app/chunks/ssr/_790a59.js:69040:12)
    at esmImport (.next/server/app/chunks/ssr/_790a59.js:68769:20)
    at Module.default (.next/server/app/chunks/rsc/_87ae68.js:130:18)
    at <unknown> (/app/entry:20:21) [<unknown> (.next/server/app/chunks/ssr/_790a59.js:191:165)]
    at Module.[project-with-next]/app/entry (ecmascript, ssr) (.next/server/app/chunks/ssr/_790a59.js:383:3)
    at <unknown> (.next/server/app/chunks/ssr/_790a59.js:68959:21)
    at runModuleExecutionHooks (.next/server/app/chunks/ssr/_790a59.js:68998:5)
    at instantiateModule (.next/server/app/chunks/ssr/_790a59.js:68958:5)
    at instantiateRuntimeModule (.next/server/app/chunks/ssr/_790a59.js:69548:12)
    at <unknown> (.next/server/app/chunks/ssr/_790a59.js:68601:1)
    at <unknown> (.next/server/app/chunks/ssr/_790a59.js:69599:39)
    at <anonymous>
    at Object.registerChunk [as push] (.next/server/app/chunks/ssr/_790a59.js:69599:25)
    at Object.<anonymous> (.next/server/app/chunks/rsc/_87ae68.js:1:41)
    at Module._compile (node:internal/modules/cjs/loader:1165:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1219:10)
    at Module.load (node:internal/modules/cjs/loader:1043:32)
    at Function.Module._load (node:internal/modules/cjs/loader:878:12)
    at Module.require (node:internal/modules/cjs/loader:1067:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (.next/server/app/index.js:4:1)
    at Module._compile (node:internal/modules/cjs/loader:1165:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1219:10)
    at Module.load (node:internal/modules/cjs/loader:1043:32)
    at Function.Module._load (node:internal/modules/cjs/loader:878:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at <unknown> (node:internal/main/run_main_module:22:47)
  
  
  | Node.js exit code: 1

I have NODE_ENV=development set so this can't be it.

PS: Another issue is that I can't add multiple children to RSPCProvider . I think that's because {children} is defined as children?: ReactElement; which means it can have zero or one children. Adding a component inside QueryClientProvider which in turn has ReactQueryDevtools inside it doesn't work either: it doesn't error like this but it mysteriously isn't shown.

@oscartbeaumont oscartbeaumont mentioned this issue Jan 8, 2023
51 tasks
@oscartbeaumont
Copy link
Member

It looks like I forgot to update the docs when I changed how this is handled a while back. I will make sure I do that. Try the following:

<QueryClientProvider client={queryClient}>
    <ReactQueryDevtools />
    <RSPCProvider client={client} queryClient={queryClient}>
        <App />
    </RSPCProvider>
</QueryClientProvider>

I could be wrong but based on that error it also kinda looks like your Next 13 app directory which will not play nicely with rspc (or Tanstack Query as far as I'm aware) on the server side, ensure you are "use client";'ing the file with mounts the provider and all files using the hooks. I am not sure what Vercel recommendations are but maybe I should do that in rspc.

It's also worth noting rspc doesn't have official support for SSR so your mileage may vary with that use case. Although do feel free to file bugs you find with it and I will look into them.


Personal Notes related to this:

  • The documentation should reflect the need for adding QueryClientProvider above rspc.Provider
  • Show an example of using React Query devtools for clarity.
  • I thought I fixed the children type issue but maybe that was only on the SolidJS client

@dlight
Copy link
Author

dlight commented Jan 8, 2023

Yes I'm on next 13 app directory. When adding "use client"; this error is gone but I got other strange errors (but I gave up on react-query devtools for now and deleted everything)

And this might be off topic for this issue but, what's the blocker for rspc being supported on ssr? Is it just a matter of testing?

And.. if rspc doesn't support SSR, does it make sense for the example use FetchTransport on server and WebsocketTransport on client here? (or httpLink and wsLink on main). I mean, when running on server it will do ssr..

@lostfictions
Copy link

lostfictions commented Jan 9, 2023

To jump in on this, I also experienced some weirdness with rspc@0.1.2 in Next.

I'm not using the app directory (it's... clearly not ready for prime-time yet, and neither is the rest of the React ecosystem). But I am using Tauri and statically exporting my site with next export.

I found I had to do this, otherwise rspc would throw on server render:

export let client;

if (typeof window !== "undefined") {
  const { createClient } = require("@rspc/client");
  const { TauriTransport } = require("@rspc/tauri");

  client = createClient<Procedures>({
    transport: new TauriTransport(),
  });
}

For what it's worth, there's multiple levels of "SSR support" -- generally the minimum level is that a library does nothing during SSR, which is often fine. (For example, React Query has explicit SSR support via a few mechanisms, the most basic of which is to not attempt any query until it's hydrated client-side.) This might already be fixed on main, but I think it would be nice if rspc were similarly well-behaved.

@oscartbeaumont
Copy link
Member

I will give this a look when I have some time.

I am probably not going to officially support the Next 13 app directory until TanStack Query (and probably also tRPC) do officially because I would like to see the patterns they come up. However, that doesn't mean it won't work, I just won't recommend it's usage.

It would probably make the most sense, for now, to use the @rspc/client within Server Components (const data = await rspc.query(...)) for now and just the regular @rspc/react for Client components. This doesn't deal with hydrating React Query which depending on your use-case will cause the data to be double-fetched (once on server and once on client) but given Next.js App directory is in beta I don't think these things have been worked out yet.

I recall you being able to do something like this when Next 13 launched to trick it into treating external packages as client components which you may need to do to correctly attach the context provider. This is something I will likely build into rspc I just need to check if Vercel recommend me adding "use client"; or not.

"use client";

export * from "@rspc/react";

In terms of SSR support with the non-app directory and SolidStart that is definitely something I would accept PRs for and will work on when I am able to dedicate the time to it. If TanStack Query has SSR support I suspect nothing would stop you from just using although because I haven't tested it I wouldn't be surprised if you run across issues (although file them here or in a separate GH issue).

I wonder if the example shown by @lostfictions is not working because of the createClient or the TauriTransport? I can pretty much guarantee the Tauri transport won't work with SSR and that given Tauri uses a Rust backend logically that doesn't make sense to support. If the createClient call is the issue let me know and I will look at fixing that because it's unintended.

In terms of this @dlight as I didn't do the Next.JS example (it was a PR) I am not sure. It's possible Next.JS don't support the browser Websocket API (haven't checked) or most likely it's because you shouldn't open a subscription server-side given as far as I am aware GSSP and the SSR are returned directly to the page and not streamed so it couldn't do real-time updates which is the whole point of a subscription.

@dlight
Copy link
Author

dlight commented Jan 10, 2023

Fair enough!

About the websocket thing: it will actually error when doing ssr, but what I actually need is subscriptions (which isn't very well supported by react-query so I'm not even using it, I just wrap on a useReducer)..

I tried some approaches for disabling SSR (using dynamic imports would give a DYNAMIC_SERVER_USAGE error; and another approach would give an error I forgot about), none successful, so I ended up doing lostfictions's trick and websockets finally work.

So I guess ReactQueryDevtools will work now? (haven't tested though)

@lostfictions
Copy link

I tried some approaches for disabling SSR (using dynamic imports would give a DYNAMIC_SERVER_USAGE error; and another approach would give an error I forgot about), none successful, so I ended up doing lostfictions's trick and websockets finally work.

hmm, that's odd... dynamic(() => import('./my-component'), { ssr: false }) always works for me for any kind of interop work i've ever had to do (binding non-react components, webgl and audio, sockets, you name it). again, i suspect the app directory is at fault here -- i know they anounced it very bombastically at their conference, but everything then and now points towards it really not being ready for widespread use, and weirdness and breakage are going to be par for the course for months. (iirc some of the features they announced at next conf were based on react RFCs that were still in discussion at the time!)

@lostfictions
Copy link

I wonder if the example shown by @lostfictions is not working because of the createClient or the TauriTransport? I can pretty much guarantee the Tauri transport won't work with SSR and that given Tauri uses a Rust backend logically that doesn't make sense to support. If the createClient call is the issue let me know and I will look at fixing that because it's unintended.

i'll take a look at the source for the tauri transport when i can -- but i do want to note that tauri offers a next.js template as part of their blessed workflow, and as far as i remember said template doesn't require the use of workarounds like next/dynamic or checking for the presence of window. so i suspect there may be something specific to what rspc is doing in this case.

@oscartbeaumont oscartbeaumont mentioned this issue Feb 6, 2023
39 tasks
mnpqraven added a commit to mnpqraven/pnc-checklist that referenced this issue Feb 25, 2023
@oscartbeaumont oscartbeaumont added the v1.x A change for version 1.x.x label May 10, 2023
@oscartbeaumont oscartbeaumont mentioned this issue Dec 10, 2024
16 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v1.x A change for version 1.x.x
Development

No branches or pull requests

3 participants