adamsoffer / next-apollo

React higher-order component for integrating Apollo Client with Next.js
MIT License
482 stars 64 forks source link

next-apollo not forwarding static properties on components it wraps #74

Open Xetera opened 4 years ago

Xetera commented 4 years ago

If I'm not wrong, it's currently not possible to work with nested layouts in next-apollo because it doesn't forward the Layout property in an example like

const GroupMembersPage = GroupMembers;

GroupMembersPage.Layout = GroupLayout;

export default withApollo({ ssr: true })(GroupMembersPage);

to the _app page which is quite limiting. If this is something you are interested in supporting (and I don't see why not) I'm happy to open a PR for it

Xetera commented 4 years ago

Turns out this is not as trivial as I thought it would be. You can't simply pass Layout through, as layout might contain queries of its own and must be a part of the getDataFromTree call but as far as I understand <AppTree /> is the entire nextjs render tree but because the Layout pattern doesn't directly include the wrapping JSX into the component tree it doesn't appear in AppTree and you can't do something clever like

await getDataFromTree(
  <Layout>
    <AppTree {...props} />
  </Layout>
);

either. Trying to include it in the WithApollo component also doesn't seem to be working as I keep getting

Error while running getDataFromTree Invariant Violation: Could not find "client" in the context or passed in as an option. Wrap the root component in an , or pass an ApolloClient instance in via options

when trying to do

return (
  <ApolloProvider client={client}>
    <Layout>
      <PageComponent {...pageProps} />
    </Layout>
  </ApolloProvider>
);

Despite the layout being nested inside ApolloProvider. The big problem here seems to be that it's not possible to getData from a separate component that lives outside of the nextjs AppTree within the context of an ApolloProvider.

I'm surprised there's nothing about this with apollo in nextjs, dynamic layouts are something I use all the time in react so I'm a little concerned by how difficult it's being to implement with apollo (and how nobody else seems to be having the same problem). I realize this isn't a next-apollo issue at this point so I'll try to find a solution for it some other way and PR it once I figure it out.

Of course if you're not fetching data inside a layout then none of this is relevant and you can simply forward it to _app.js

adamsoffer commented 4 years ago

Hey @Xetera - yeah I wish dynamic/persistent layouts had first-class support in next.js. There is a workaround though; check out this guide by Adam Wathan 👉 https://adamwathan.me/2019/10/17/persistent-layout-patterns-in-nextjs/

aboveyunhai commented 3 years ago

@Xetera Do you see any solutions now? I just experienced the exist problem and realized that you were already trying all the possible ways I had done without success. It seems like the only possible way is just leaving a pure layout without data fetching inside _app.js