next.js useQuery是否在服务器端渲染上运行?

xienkqul  于 2023-05-28  发布在  其他
关注(0)|答案(1)|浏览(128)

我是Next.js的新手,对Next.js中的客户端渲染和服务器端渲染有一些疑问
1.我看到有两种方法可以在Next.js上获取数据。其中之一是使用useQuery钩子,但它只能在React组件函数上调用。这是否意味着它只在从客户端呈现页面时运行?
1.我读了一篇关于如何将apolloClient连接到Next.js的文章。上面说
始终为SSR创建apolloClient的新示例,并且仅为CSR创建一个apolloClient示例
下面是示例代码

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;
  }

有人能解释一下吗?如果问题很傻我很抱歉

eiee3dmh

eiee3dmh1#

在Next.js中:

  • SSR -服务器端渲染-getServerSideProps
  • SSG -生成的静态站点-getStaticPathsgetStaticProps
  • CSR -客户端渲染-其他所有内容

需要注意的是,SSG函数是在服务器端运行的。
在客户机上,您只需要创建Apollo Client的单个全局示例。创建Apollo Client的多个示例将使与客户端保持同步变得非常困难。这个困难是因为Apollo Cache、Apollo Link等都将存储在Apollo Client的不同示例中。
在Next中,通常将Apollo Client的全局示例放在页面_app.js上并使用Apollo Provider。在其他客户端页面上,您将使用useQuery钩子来调用单个全局示例。
服务器端(SSR)函数getStaticPropsgetServerSideProps不能访问Apollo的客户端示例、Next的客户端示例或其他服务器端函数。因此,您必须在使用getStaticPathsgetStaticPropsgetServerSideProps并需要访问Apollo客户端的每个页面上定义Apollo连接,否则它将无法用于服务器端调用。
由于第一个rule of hooks是它们只能在顶层(客户端)调用,因此不能在服务器端函数中使用它们。不能,您不能在Next SSR或SSG函数中运行useQuery
您提供的示例是保持该高速缓存同步,并且在定义客户端的方式上已经过时。这里是一个简化的例子,更沿着官方文档。
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-所有客户端页面都使用的单个示例,因为它 Package 了整个应用程序

import graphqlClient from 'my/path/graphqlClient';

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

由于Apollo客户端将应用程序 Package 在_app.js中,因此客户端的每个页面/组件都可以使用useQuery钩子
客户端查询

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

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

每个使用SSR或SSG函数并需要访问Apollo的页面都必须示例化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});
};

最后,为了简化,你可以使用graphql-code-generator来自动生成Apollo查询、变异等。hooks(以及TS用户的类型)以及服务器端兼容的query and mutation functions for Next.js

相关问题