如何从 NextJS 服务器为 Apollo 客户端补充水分
Posted
技术标签:
【中文标题】如何从 NextJS 服务器为 Apollo 客户端补充水分【英文标题】:How to hydrate Apollo client from NextJS server 【发布时间】:2019-09-15 23:34:39 【问题描述】:我正在使用带有 Apollo 客户端的自定义 NextJS 服务器。我想在服务器端获取 GraphQL 数据,然后将其发送到客户端。我有点能够做到这一点,但客户端再次获取它。我了解 Apollo 缓存仅在服务器上可用,然后需要发送到客户端并从那里恢复。
Apollo docs 提到了 s-s-r,但我不想使用 Apollo 客户端完全渲染我的应用程序,我想使用 NextJS,我只想从 Apollo 客户端获取数据并手动将其注入 html 以在客户端恢复它。我查看了一些使用 Apollo 的 NextJS 示例,但没有一个显示如何做到这一点。
这是我的自定义请求处理程序:
const app = next( dev: process.env.NODE_ENV !== 'production' );
const customHandler = async (req, res) =>
const rendered = await app.renderToHTML(req, res, req.path, req.query);
// somehow get the data from the apollo cache and inject it in the rendered html
res.send(rendered);
【问题讨论】:
【参考方案1】:当您在服务器中创建ApolloClient
时,您可以传递initialState
来水合缓存。
const createApolloClient = ( initialState, headers ) =>
new ApolloClient(
uri: GRAPHQL_URL,
cache: new InMemoryCache().restore(initialState || ) // hydrate cache
);
export default withApollo(PageComponent, s-s-r = true = ) =>
const WithApollo = ( apolloClient, apolloState, ...pageProps ) =>
const client = apolloClient || createApolloClient( initialState: apolloState, headers: );
... rest of your code.
);
);
我为此创建了一个名为nextjs-with-apollo
的包。看看https://github.com/adikari/nextjs-with-apollo。一旦你安装了这个包,就创建一个 HOC。
// hocs/withApollo.js
import withApollo from 'nextjs-with-apollo';
import ApolloClient from 'apollo-client';
import InMemoryCache from 'apollo-cache-inmemory';
const GRAPHQL_URL = 'https://your-graphql-url';
const createApolloClient = ( initialState, headers ) =>
new ApolloClient(
uri: GRAPHQL_URL,
cache: new InMemoryCache().restore(initialState || ) // hydrate cache
);
export default withApollo(createApolloClient);
然后您可以将 hoc 用于您的 next
页面。
import React from 'react';
import useQuery from '@apollo/react-hooks';
import withApollo from 'hocs/withApollo';
const QUERY = gql`
query Profile
profile
name
displayname
`;
const ProfilePage = () =>
const loading, error, data = useQuery(PROFILE_QUERY);
if (loading)
return <p>loading..</p>;
if (error)
return JSON.stringify(error);
return (
<>
<p>user name: data.profile.displayname</p>
<p>name: data.profile.name</p>
</>
);
;
export default withApollo(ProfilePage);
【讨论】:
以上是关于如何从 NextJS 服务器为 Apollo 客户端补充水分的主要内容,如果未能解决你的问题,请参考以下文章
使用 Apollo 客户端在 nextJs 中传递授权标头的最佳方法? ReferenceError: localStorage 未定义
如果你有 apollo react 钩子从后端获取数据,你如何使用 nextjs 进行服务器端渲染?
在 nextJS 上配置 apollo 客户端以进行订阅的问题