【问题标题】:How to hydrate Apollo client from NextJS server如何从 NextJS 服务器为 Apollo 客户端补充水分
【发布时间】:2019-09-15 23:34:39
【问题描述】:

我正在使用带有 Apollo 客户端的自定义 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);
}

【问题讨论】:

    标签: javascript reactjs apollo react-apollo next.js


    【解决方案1】:

    当您在服务器中创建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);
    

    然后您可以将 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);
    

    【讨论】:

      猜你喜欢
      • 2021-02-05
      • 2020-06-12
      • 2016-08-31
      • 2019-09-17
      • 2019-11-26
      • 2021-10-28
      • 2020-08-27
      • 2020-01-30
      • 2023-04-02
      相关资源
      最近更新 更多