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

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

我是Nextjs新手,对Nextjs中的客户端渲染和服务器端渲染有一些疑问

  • 我知道有两种方法可以在Nextjs上获取数据。其中之一是使用
    useQuery
    hook,但只能在React组件函数上调用。这是否意味着它仅在从客户端呈现页面时运行
  • 我读了一篇关于如何将
    apolloClient
    连接到Nextjs的帖子。据说
  • 始终为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;
      }
    
    
    有人能解释一下吗?如果下一篇JS中的问题很愚蠢,我很抱歉:

    • -服务器端呈现-getServerSideProps
    • -生成静态站点-GetStaticPath/getStaticProps
    • CSR-客户端渲染-其他一切
    需要注意的是,SSG是服务器端的

    在客户端(CSR)上,您只需要创建Apollo客户端的单个全局实例。创建多个Apollo客户端实例将使在客户端上保持同步成为一项挑战。这个困难是因为Apollo缓存、Apollo链接等都将存储在Apollo客户端的不同实例中

    接下来,将Apollo客户端的全局实例放在页面
    \u app.js
    上并使用。在其他客户端页面上,您将使用调用单个全局实例的钩子

    服务器端(SSR)函数getStaticProps或getServerSideProps无权访问Apollo的客户端实例、Next的客户端实例或其他服务器端函数。因此,您必须在使用GetStaticPath、getStaticProps或getServerSideProps并需要访问Apollo客户端的每个页面上定义Apollo连接,否则服务器端调用将无法使用该连接

    因为,第一个问题是它们只能在顶层(客户端)调用,所以不能在服务器端函数中使用它们。不,您不能在下一个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-所有客户端页面都使用的单个实例,因为它包装了整个应用程序

    import graphqlClient from 'my/path/graphqlClient';
    
    const App = ({ Component, pageProps }) => {
      const client = graphqlClient();
      return (
        <ApolloProvider client={client}>
          <Component {...pageProps} />
        </ApolloProvider>
      );
    };
    
    每个使用SSR或SSG函数并需要访问Apollo的页面都必须实例化Apollo的新实例

    SSG

    固态继电器


    谢谢你的回答。它非常详细,帮助很大。还有一个问题,每当我们创建Apollo客户端实例时,它也会创建Apollo缓存、Apollo链接等等,对吗?服务器端不必对它做任何事情(Apollo缓存、Apollo链接)?Apollo将在创建客户端时添加您定义的任何内容。在上面的示例中,定义了缓存和链接,并可用于服务器和客户端。但是,服务器端调用只能访问其一个客户端及其当前状态。因此,SSR缓存本质上是空的,或者只包含在调用时在同一SSR函数中进行的Apollo调用。有很多方法可以将服务器端调用配置为彼此更加同步,但这本身就是一篇完整的文章,并不总是需要的——特别是在SSG站点中。
    import { gql, useQuery } from '@apollo/client';
    import graphqlClient from 'my/path/graphqlClient';
    
    const About = () => {
     const { data } = useQuery(YOUR_QUERY); // uses your single instance defined in _app.js
     const { data } = await client.query({query: YOUR_QUERY});
     return (
       ...
     )
    }
    
    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});
    };
    
    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});
    };