我在Apollo Client中使用自定义的NextJS服务器。我想获取GraphQL数据服务器端,然后将其发送到客户端。我确实能够做到这一点,但是客户端又再次获取了它。我知道Apollo缓存仅在服务器上可用,然后需要发送到客户端并从那里还原。
Apollo docs提到了SSR,但我不想使用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);
}
答案 0 :(得分:0)
在服务器中创建ApolloClient
时,可以传递initialState
来缓存缓存。
const createApolloClient = ({ initialState, headers }) =>
new ApolloClient({
uri: GRAPHQL_URL,
cache: new InMemoryCache().restore(initialState || {}) // hydrate cache
});
export default withApollo(PageComponent, { ssr = 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);
然后,您可以像这样在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);