react-apollo-hooks icon indicating copy to clipboard operation
react-apollo-hooks copied to clipboard

Make useQuery work with with getDataFromTree (server side rendering)

Open craigcbrunner opened this issue 6 years ago • 12 comments
trafficstars

I am using next.js with Apollo, and have been writing Hooks based components. I noticed react-apollo-hooks doesn't seem to work with getDataFromTree when it does SSR and fills the cache. If I use <Query /> from react-apollo it correctly sets the initial data in the apollo cache and doesn't refetch it, but useQuery only seems to fetch client side... is this expected/going to be fixed?

craigcbrunner avatar Jan 07 '19 02:01 craigcbrunner

@craigcbrunner It will be partially fixed in #44 (should be merged soon). It will provide API for server-side rendering components using react-apollo-hooks. It won't support SSR for components using both react-apollo and react-apollo-hooks, but it will be possible to add it later - please let me know if it's a case for you.

trojanowski avatar Jan 07 '19 22:01 trojanowski

@craigcbrunner if you are following the with-apollo example from the next.js github, you should be able to replace the following line with getMarkupFromTree provided by react-apollo-hooks - https://github.com/zeit/next.js/blob/canary/examples/with-apollo/lib/with-apollo-client.js#L23

Your code will look something like:

//... imports
import { renderToString } from 'react-dom/server';
import { getMarkupFromTree } from 'react-apollo-hooks';

// ... code from next.js
        await getMarkupFromTree({
            renderFunction: renderToString,
            tree: <App {...appProps} Component={Component} router={router} apolloClient={apollo} />,
        });

It looks to be SSRing for me without any errors.

That's the basic implementation of how react-apollo defines getDataFromTree - https://github.com/apollographql/react-apollo/blob/327edc5d81f352fa9e00854eb82ef08e7e2c75b6/src/getDataFromTree.ts#L86

Does this seem reasonable @trojanowski?

treyhuffine avatar Jan 23 '19 16:01 treyhuffine

@craigcbrunner Yes, that's correct.

trojanowski avatar Jan 25 '19 08:01 trojanowski

Just a +1 for supporting server rendering of legacy react-apollo query components and HOCs alongside the support for useQuery. Looks like it shouldn't be particularly difficult to harmonize these two.

jamesreggio avatar Jan 27 '19 04:01 jamesreggio

@craigcbrunner if you are following the with-apollo example from the next.js github, you should be able to replace the following line with getMarkupFromTree provided by react-apollo-hooks - https://github.com/zeit/next.js/blob/canary/examples/with-apollo/lib/with-apollo-client.js#L23

Your code will look something like:

//... imports
import { renderToString } from 'react-dom/server';
import { getMarkupFromTree } from 'react-apollo-hooks';

// ... code from next.js
        await getMarkupFromTree({
            renderFunction: renderToString,
            tree: <App {...appProps} Component={Component} router={router} apolloClient={apollo} />,
        });

It looks to be SSRing for me without any errors.

That's the basic implementation of how react-apollo defines getDataFromTree - https://github.com/apollographql/react-apollo/blob/327edc5d81f352fa9e00854eb82ef08e7e2c75b6/src/getDataFromTree.ts#L86

Does this seem reasonable @trojanowski?

Doesn't this render the whole tree twice on the server? once for nextjs and once to extract the apollo-cache?

usually getMarkupFromTree returns the markup which will be sent to the client, but with nextjs, this is done internally

macrozone avatar Apr 01 '19 09:04 macrozone

I can confirm that @treyhuffine's suggestion works. I would however prefer a more "elegant" way of doing this :)

madsobel avatar Apr 03 '19 18:04 madsobel

This issue seems to be related to the one I opened here, but after implementing the code as described above, the queries still run after I load a page, when using ApolloConsumer, and then running the query inside of a react hook (doing it this way because I need to specify the client, as I have two in my application).

paulgrieselhuber avatar Apr 17 '19 12:04 paulgrieselhuber

I've recently worked on a more elegant solution for this that's temporary until actual suspense lands in React. It still applies the two pass approach, but it should be more efficient than actually rendering the tree repeatedly.

Maybe someone here will find it useful :smile: https://github.com/FormidableLabs/react-ssr-prepass

kitten avatar May 17 '19 11:05 kitten

@kitten do you have an idea how it could be used with hooks? In the example at https://github.com/FormidableLabs/react-ssr-prepass the fetchData method is used, but hooks are called inside of functional components.

trojanowski avatar May 17 '19 12:05 trojanowski

@trojanowski It supports the current spec/API for suspense, so you can throw a promise any time and as react-ssr-prepass is walking the tree it'll queue them up and suspend on those.

kitten avatar May 17 '19 12:05 kitten

@craigcbrunner It will be partially fixed in #44 (should be merged soon). It will provide API for server-side rendering components using react-apollo-hooks. It won't support SSR for components using both react-apollo and react-apollo-hooks, but it will be possible to add it later - please let me know if it's a case for you.

Hi, could you please clarify how it should be used? I don't need to support "react-apollo" components, only hooks so that sounds ok to me. However I don't get which call to make in this case?

Edit: this seems like an old issue actually but I seem to have similar problem on newer v3 of Apollo.

eric-burel avatar May 12 '20 09:05 eric-burel

Ok after more investigation this issue seems stale. useQuery in itself is fine, but Apollo v3 is in beta version and people are experiencing silently failing SSR a lot https://github.com/apollographql/react-apollo/issues/3678

eric-burel avatar May 12 '20 14:05 eric-burel