NextJS + Apollo:如何在 getServerSideProps 内的 apolloClient.query 上获取多个查询?
Posted
技术标签:
【中文标题】NextJS + Apollo:如何在 getServerSideProps 内的 apolloClient.query 上获取多个查询?【英文标题】:NextJS + Apollo: How to get multiple queries on apolloClient.query inside getServerSideProps? 【发布时间】:2021-10-08 16:31:51 【问题描述】:我目前正在学习 NextJS + Apollo,但遇到了一个问题。因为不推荐getInitialProps
,所以我使用getServerSideProps
。在这里,我使用此代码来获取服务器端的 props 并填充组件:
export async function getServerSideProps()
// eslint-disable-next-line no-debugger
const apolloClient = initializeApollo();
await apolloClient.query(
query: GET_BANNER_DATA,
);
return addApolloState(apolloClient,
props: ,
);
问题在于getServerSideProps
只能用于页面级别,不能用于组件。因此,我必须为我在此页面上使用的所有组件获取道具。
我该怎么做? apolloClient.query
接受多个查询吗?或者我应该对addApolloState
函数做些什么?
官方文档没有考虑到这一点,我在另一个开源项目中找不到类似的东西。
【问题讨论】:
【参考方案1】:我认为getServerSideprops
应该只用于页面本身。但是,您可以在页面上包含多个组件,并让每个组件查询自己的数据客户端。
const Page = () =>
return <Component/>
...
const Component = () =>
// do query here
【讨论】:
1.这意味着我应该将所有组件放在一个文件中。如果是这样,这是一个坏主意,对吧? 2.即使我这样做,我相信我也只能使用一次getServerSideProps
,我最初的问题仍然存在。 3. 我在标题中提到了 Apollo,所以我很想得到一个包含 Apollo 函数的答案。我知道如何使用其他方法(获取等)来做到这一点,但我似乎无法找到答案。不过还是谢谢!
1.不,您可以在任何地方创建组件并导入它们,您不需要在同一个文件中创建它们。 2.您最初的问题不存在,忘记getServerSideProps,这无关紧要,只需将组件用于您的用例即可。 3. 你可以在每个组件中使用 useQuery(Query) 或 client.query,如果你想知道 apollo 是如何工作的,那就提出一个新的问题。忘记尝试获取道具服务器端,获取数据客户端。
1.是的,我可以导入它们,但我不能在导出时进行查询(或者这样做会很复杂)。 2. 不,我需要getServerSideProps
,因为我必须在服务器端呈现页面以用于 SEO。我只知道如何在客户端执行此操作。 3.与第2点相同。我知道我可以在组件内部使用useQuery(Query)
,但我想知道如何在服务器端执行此过程。【参考方案2】:
您可以在一个查询中组合查询。举个例子吧。
query posts($month: Int!)
posts(month: $month)
id,
name,
query notes($month: Int!)
notes(month: $month)
id,
name,
可以合二为一:
query postsAndNotes($month: Int!)
posts(month: $month)
id,
name,
notes(month: $month)
id,
name,
查询结果会有帖子和笔记对象。
【讨论】:
我认为这不是我的解决方案。我已经为每个组件分离了查询并给出了一个变量;这就是为什么您在我的情况下看到“GET_BANNER_DATA”而不是查询的原因。我可以这样做吗?为什么要使用变量? 我明白你的意思。要在 getServerSideProps 上运行它,您需要获取所有内容并将它们传递给您的组件,除非您不考虑客户端获取。创建一个查询来获取您想要的所有数据。如果您的其他查询取决于某些参数,您需要弄清楚您的调用顺序和架构。【参考方案3】:在我看来,解决这个问题有两种可能的选择。对于它们两者,您都需要确保可以在页面级组件中导入必要的查询。我喜欢通过在使用它的组件的文件中定义查询,然后将其导出,这样当您描述的页面出于性能原因需要它时,他们可以导入它并保持相对干燥。
从那里,我将假设查询不相互依赖(即,一个查询的结果被输入到下一个查询的变量中)。
解决方案 1 涉及将两个查询组合成一个查询,然后发出该请求。我还没弄明白。
不过,解决方案 2 涉及利用 Promises,特别是 Promise.all
const query1 = apolloClient.query(
query: GET_BANNER_DATA,
);
const query2 = apolloClient.query(
query: SOME_OTHER_QUERY,
);
Promise.all([query1, query2]).then(
(responses) =>
// Do some manipulation of the data responses
);
return addApolloState(apolloClient,
// You'll pass whatever props you need for the page to render here,
// but shouldn't need to do anything for the sub-components.
// When they go to make their queries, the data will already be in the local Apollo cache
props: ,
);
【讨论】:
以上是关于NextJS + Apollo:如何在 getServerSideProps 内的 apolloClient.query 上获取多个查询?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 NextJS 服务器为 Apollo 客户端补充水分
如何在 NextJS 应用程序中从 Apollo 链接上下文访问 Express HTTP 请求?
如果你有 apollo react 钩子从后端获取数据,你如何使用 nextjs 进行服务器端渲染?