Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does useQuery run on server-side rendering?

I'm new to Nextjs and have some questions about client-side rendering and server-side rendering in Nextjs

  1. I see there are two ways to fetched data on Nextjs. One of them is to use useQuery hook but only callable on React component function. Does it mean that it only running when rendering the page from the client-side
  2. I read a post about how to connect apolloClient to Nextjs. It said that

always create a new instance of apolloClient for SSR and only create one instance of apolloClient for CSR

Here is the example code

  export function initializeApollo(initialState = null) {
    const _apolloClient = apolloClient ?? createApolloClient();

    // If your page has Next.js data fetching methods that use Apollo Client,
    // the initial state gets hydrated here
    if (initialState) {
      // Get existing cache, loaded during client side data fetching
      const existingCache = _apolloClient.extract();

      // Restore the cache using the data passed from
      // getStaticProps/getServerSideProps combined with the existing cached data
      _apolloClient.cache.restore({ ...existingCache, ...initialState });
    }

    // For SSG and SSR always create a new Apollo Client
    if (typeof window === "undefined") return _apolloClient;

    // Create the Apollo Client once in the client
    if (!apolloClient) apolloClient = _apolloClient;
    return _apolloClient;
  }

Can anyone explain that? I'm sorry if the question are silly

like image 539
Tu Le Thanh Avatar asked Apr 19 '21 14:04

Tu Le Thanh


People also ask

Can you use Apollo client on a server?

Apollo Client provides a handy API for using it with server-side rendering, including a function that executes all of the GraphQL queries that are required to render your component tree. You don't need to make any changes to your queries to support this API.

Does Nextjs use server-side rendering?

Next. js has two forms of pre-rendering: Static Generation and Server-side Rendering.

Is Nextjs client or server?

Next. js is used for server side rendering of react application . React along with other framework like angular and vue. js are traditional client side framework ,they run in browser but there are technology to run this framework on server side, and next.

Is GraphQL server-side or client-side?

A GraphQL server is a server-side implementation of the GraphQL spec. In other words, a GraphQL server exposes your data as a GraphQL API that your client applications can query for data. These clients could be a single page application, a CMS like Drupal, a mobile app, or almost anything.

What is server side rendering used for?

The most common use case for server-side rendering is to handle the initial render when a user (or search engine crawler) first requests our app. When the server receives the request, it renders the required component (s) into an HTML string, and then sends it as a response to the client.

What is the difference between react-side rendering and server side rendering?

It renders the JavaScript and fills the content into it. Server-side rendering, on the other hand, renders the React components on the server. The output is HTML content.

What is the difference between client-side and server-side rendering?

What’s the difference between client-side rendering and server-side rendering? In Client-side rendering, your browser downloads a minimal HTML page. It renders the JavaScript and fills the content into it. Server-side rendering, on the other hand, renders the React components on the server.

What is server-side rendering in Redux?

Redux's only job on the server side is to provide the initial state of our app. In the following recipe, we are going to look at how to set up server-side rendering. We'll use the simplistic Counter app as a guide and show how the server can render state ahead of time based on the request.


1 Answers

In Next JS:

  • SSR - Server side rendering - getServerSideProps
  • SSG - Static site generated - getStaticPaths & getStaticProps
  • CSR - Client side rendering - everything else

It is important to note that SSG functions are run server-side.

On the client, you only want to create a single global instance of Apollo Client. Creating multiple instances of Apollo Client will make it challenging to keep things in sync with the client. This difficulty is because the Apollo Cache, Apollo Link, etc., will all be stored in different instances of Apollo Client.

In Next, it is common to place the global instance of Apollo Client on the page _app.js and use the Apollo Provider. On the other client-side pages, you'd use the useQuery hook that calls your single global instance.

The server-side (SSR) functions getStaticProps or getServerSideProps do not have access to the client instance of Apollo, client instance of Next, or other server-side functions. Because of this, you must define your Apollo connection on every page that uses getStaticPaths, getStaticProps, or getServerSideProps and needs access to the Apollo client or it will not be available to the server-side calls.

Since the first rule of hooks is that they must only be called at the top level (client-side), you cannot use them in server-side functions. No, you cannot run useQuery in the Next SSR or SSG functions.

The example you provide is keeping the cache in sync and is outdated in how it is defining the client. Here is a simplified example more along the lines of the official docs.


graphqlClient.js

import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';

// Used server and client side - can't use react hooks
export const graphqlClient = new ApolloClient({
  cache: new InMemoryCache(),
  link: new HttpLink({
    uri: 'YOUR_GQL_ENDPOINT',
  }),
  ssrMode: typeof window === 'undefined',
});

_app.js - a single instance that all client pages use because it wraps the whole app

import graphqlClient from 'my/path/graphqlClient';

const App = ({ Component, pageProps }) => {
  const client = graphqlClient();
  return (
    <ApolloProvider client={client}>
      <Component {...pageProps} />
    </ApolloProvider>
  );
};

Every page/component that is client-side that can use the useQuery hook because Apollo Client is wrapping the app in _app.js

Client-side query

import { gql, useQuery } from '@apollo/client';

const About = () => {
 const { data } = useQuery(YOUR_QUERY); // uses your single instance defined in _app.js
 return (
   ...
 )
}

Every page that uses SSR or SSG functions and needs access to Apollo must instantiate a new instance of Apollo.

SSG

import graphqlClient from 'my/path/graphqlClient';

//does not have access to _app.js or client and must define new Apollo Client instance
export const getStaticProps = async () => {
  const client = graphqlClient();//
  const { data } = await client.query({query: YOUR_QUERY});
};

export const getStaticPaths = async () => {
  const client = graphqlClient();
  const { data } = await client.query({query: YOUR_QUERY});
};

SSR

import graphqlClient from 'my/path/graphqlClient';

//does not have access to _app.js or client and must define new Apollo Client instance
export const getServerSideProps = async () => {
  const client = graphqlClient();
  const { data } = await client.query({query: YOUR_QUERY});
};

Lastly, to simplify things you can use graphql-code-generator to auto-generate Apollo query, mutation, etc. hooks (and types for TS users) as well as server-side compatible query and mutation functions for Next.js.

like image 169
Sean W Avatar answered Jan 01 '23 08:01

Sean W