0

In my apps my store is usually the main abstraction layer that sits between the app and the API. By ensuring my React tree only references store methods when making API calls, I have a clear separation of concerns and am able to edit API related code confidently.

I am having trouble making this paradigm work with server components.

I am defining the store like so:

"use client";

...

const Context = createContext<Store | undefined>(undefined);

export default function AppProvider({ session, children }) {
  const storeInstance = useMemo(() => createStore(session), []);
  return (
    <Context.Provider value={storeInstance}>
      {children}
    </Context.Provider>
  );
}

export const useApp = () => useContext(Context);

In client components I can call useApp to have access to my store and its state/methods.

However, I cannot do that in server components, as that would require importing and calling useApp from a server component.

My root layout looks like this:

export default async function RootLayout({ children }) {
  const client = createDatabaseAndAuthClient()
  return (
    <AppProvider session={await getSession(client)}>
     ...
    </AppProvider>
  );
}

This works for client components but I cannot figure out a way of giving server components access to the store when it's instantiated on the server. My attempts at defining it as a singleton export have failed.

How can I feed it through to server components, so that I can do something like:

import { store } from "@/lib/store";

export default async function Home() {
  const user = await store.getUser();
  return (
    <>Hello from the server, {user.name}!</>
  );
}

or perhaps there is a different way altogether? Advice appreciated.

styke
  • 2,116
  • 2
  • 23
  • 51
  • As stated [here](https://nextjs.org/docs/messages/context-in-server-component), Context is fully supported within client components but not server components. – Fabio Nettis Jul 13 '23 at 14:36
  • Yes, that much is evident. What would be the correct way of sharing modules between server/client components, if we cannot pass them to server components using context? Would there have to be 2 separate instantiation and referencing approaches? – styke Jul 13 '23 at 14:53
  • Server components are not meant to be stateful at all. But rather execute fetch logic using [request deduping](https://nextjs.org/docs/app/building-your-application/data-fetching/caching#per-request-caching). The idea generally is that multiple server components access the same resource while only ever the first request is executed. If you need shared data, either pass it as props or store it in a server session and as client context. – Fabio Nettis Jul 14 '23 at 05:30
  • That's interesting, as Next JS recommends moving client components to leaves, meaning that components up until that point would mostly be server rendered. Even if using server components just for basic layout, in complex apps I imagine UI state would still be necessary to render things correctly. Anyways, thanks for your advice. – styke Jul 15 '23 at 04:47

0 Answers0