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

2023-12-26

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

  1. 我发现 Next.js 有两种获取数据的方法。其中之一是使用useQueryhook,但只能在 React 组件函数上调用。这是否意味着它仅在从客户端渲染页面时运行?
  2. 我读了一篇关于如何连接的文章apolloClient到 Next.js。它说

总是创建一个新实例apolloClient对于SSR,只创建一个实例apolloClient for CSR

这是示例代码

  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中:

  • SSR https://nextjs.org/docs/basic-features/pages#server-side-rendering- 服务端渲染 -getServerSideProps
  • SSG https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation- 生成静态站点 -getStaticPaths & getStaticProps
  • CSR - 客户端渲染 - 其他一切

值得注意的是,SSG 功能是在服务器端运行的。

在客户端上,您只想创建 Apollo Client 的单个全局实例。创建 Apollo Client 的多个实例将使保持与客户端同步变得困难。这个困难是因为 Apollo Cache、Apollo Link 等都将存储在 Apollo Client 的不同实例中。

接下来,常见的是将Apollo Client的全局实例放在页面上_app.js并使用阿波罗提供商 https://www.apollographql.com/docs/react/api/react/hooks/#example。在其他客户端页面上,您可以使用useQuery https://www.apollographql.com/docs/react/api/react/hooks/#example-2调用您的单个全局实例的钩子。

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

自从第一次钩子规则 https://reactjs.org/docs/hooks-rules.html是它们只能在顶层(客户端)调用,不能在服务器端函数中使用它们。不,你不能跑useQuery在下一个 SSR 或 SSG 功能中。

您提供的示例是保持缓存同步,并且是定义客户的方式已经过时 https://www.apollographql.com/docs/react/performance/server-side-rendering/#rehydrating-the-client-side-cache。这是一个更符合官方文档的简化示例。


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

每个客户端页面/组件都可以使用 useQuery 钩子,因为 Apollo 客户端将应用程序包装在_app.js

客户端查询

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 代码生成器 https://www.graphql-code-generator.com/自动生成 Apollo 查询、变异等钩子(以及 TS 用户的类型)以及服务器端兼容Next.js 的查询和变异函数 https://www.graphql-code-generator.com/docs/plugins/typescript-apollo-next.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

useQuery 是否在服务器端渲染上运行? 的相关文章

随机推荐

  • InvalidCharacterError 仅在 IE 中出现

    我们有一个订单表单 它使用 ziplookup 功能 当在字段中输入邮政编码时 城市 县 州和邮政编码也会输入到同一字段中 tr td class formLabel Zip Code td td class formColon nbsp
  • SwiftUI 和 NavigationView 的动画错误可能是什么原因造成的?

    我一直在尝试一些 SwiftUI 布局 我想尝试的事情之一是创建一个简单的圆形进度环 在对代码进行了一段时间的研究之后 我设法让一切都按照我希望的方式工作 至少对于原型来说是这样 当我将此视图嵌入到 SwiftUI NavigationVi
  • 将 python 日期格式 (%Y) 转换为 java (yyyy)

    我有很多时间格式 格式如下 Y m d H M S 有没有快速的方法或库将它们转换为 YYYY MM DD HH MM SS 我当前的方法是使用字符串替换 但也许我会错过一些边缘情况 我可能的格式化程序是 d b Y y H M S p f
  • Node.JS deflate/gzip 响应文本

    我看到了所示的示例here http nodejs org api zlib html zlib examples response writeHead 200 content encoding deflate raw pipe zlib
  • 在可能保存模型时处理 ember-data 中的自定义服务器端错误

    保存模型时是否有正确的方法来处理自定义错误 举个例子 假设我有一个只有两个属性 名称 和 值 的模型 当我这样做时 var myModel this get store createRecord myModel name someName
  • IE9 中 的边框半径错误

    看见那个 div 元素正确渲染边框 边框半径 但任何 a or a div
  • 如何使用 JavaScript 获取滚动条位置?

    我正在尝试使用 JavaScript 检测浏览器滚动条的位置 以确定当前视图在页面中的位置 我的猜测是 我必须检测拇指在轨道上的位置 然后检测拇指的高度占轨道总高度的百分比 我是否过于复杂化了 或者 JavaScript 是否提供了比这更简
  • 当在 contenteditable 按钮中输入空格时,Chrome 会触发 onClick

    我有一个按钮contenteditable true 我可以很好地编辑文本 但无法在 Chrome 中输入空格 当我按下空格键时 Chrome 会在按钮上触发 onClick 事件 然而 Safari 会按照您的预期插入一个空格 使用此代码
  • C++ 的类似 Hibernate 的层

    在 C 中使用 DB 确实是一团糟 当我转向 Java 并能够使用统一的系统将整个层抽象出来 又名 Hibernate 时 这真是令人耳目一新 有几个用于 DB 的 C 抽象层 但它们通常是特定于供应商的 并且只有一个薄层包装了真正的 C
  • 我想单击列表视图中的任意位置(空白区域)

    作为一名新的 Android 程序员 我必须运行我的待办事项应用程序 对于圣诞节购物来说这是可以接受的 但我真的很想让整个列表项行可单击 现在我必须点击文本 物品越短越难击中 我的主要活动扩展了 ListActivity 我将 Resour
  • rspec 测试中 Rails 应用程序的端口号

    我想使用 rspec 结合 Faraday 和 Faraday middleware 来测试 Rails 应用程序的 json 响应 要使用 Faraday 需要应用程序 URL 在测试中我想使用本地主机 端口号 问题是 如何在 rspec
  • 如何在编辑 XML 文件时运行我的项目?

    当我编辑 XML 文件并尝试运行 Android 项目 通过单击工具栏中的 播放 按钮或 command shift F11 时 没有任何反应 我必须切换到我也在编辑的 java 文件才能运行该项目 我怎样才能解决这个问题 您无法运行 xm
  • (PyQt) QTreeView - 想要展开/折叠所有子级和孙级

    我希望能够展开或折叠 QTreeView 中特定分支的所有子级 我正在使用 PyQt4 我知道 QTreeView 有一个绑定到 的展开所有子项功能 但我需要两件事 它需要绑定到不同的组合键 shift space 我还需要能够折叠所有子项
  • React Native - 无法执行 JS 调用:__fbBatchedBridge 未定义

    我一直在关注这个教程https www raywenderlich com 126063 react native tutorial https www raywenderlich com 126063 react native tutor
  • 如何使用Python将主机名添加到known_hosts?

    我正在使用此代码将服务器添加到known hosts subprocess Popen sshpass p password ssh o StrictHostKeyChecking no add key stdout subprocess
  • SELECT DISTINCT 可以与 Perl 的 DBD::CSV 一起使用吗?

    我在网上找到了一个 SELECT example 当我在脚本中尝试它时 我收到此错误消息 Specifying DISTINCT when using aggregate functions isn t reasonable ignored
  • 在Android Gradle任务中获取编译后的.class输出目录

    我正在为我的 Android 项目创建一个 Gradle 任务 它需要知道编译后的路径 class文件 我怎样才能得到这条路径 我找到了建议 here https stackoverflow com a 26667774 3004881 a
  • Nuxtjs 与 scrollmagic 给我“窗口未定义”

    我想将scrollmagic 与nuxtjs 一起使用 我通过npm安装了scrollmagic npm install scrollmagic 在我的 nuxt config js 文件中我添加了 build vendor scrollm
  • 有没有办法否定正则表达式?

    给定一个正则表达式R它描述了一种常规语言 没有花哨的反向引用 有没有一种算法方法来构造正则表达式R 描述除以下描述的单词之外的所有单词的语言R 应该可以作为维基百科 http en wikipedia org wiki Regular la
  • useQuery 是否在服务器端渲染上运行?

    我是 Next js 的新手 对 Next js 中的客户端渲染和服务器端渲染有一些疑问 我发现 Next js 有两种获取数据的方法 其中之一是使用useQueryhook 但只能在 React 组件函数上调用 这是否意味着它仅在从客户端