javascript - NextJS SSR 可以与 Apollo 客户端一起使用吗?在第一次加载页面上检查 'view page source' 时,我看不到我的 HTML

标签 javascript graphql apollo next.js apollo-client

编辑:这不工作,因为我没有打电话getInitialProps ? NextJS 文档(https://nextjs.org/docs/basic-features/data-fetching#server-side-rendering)说,如果你不这样做,那么页面会在构建时静态呈现。所以我应该把我的useQuery里面 getInitialProps ?

我正在测试一个通过 GraphQL 连接到 KeystoneJS CMS 后端的 Apollo 客户端前端。据我了解,测试 SSR 是否正常工作的一种方法是在浏览器中加载页面,检查源代码并查看 HTML 是否在其中。它不适合我。

页面源码如下(很丑,我只是在测试连接和SSR工作):

import React from 'react';
import Head from 'next/head';
import {useQuery} from '@apollo/react-hooks';
import gql from 'graphql-tag';

const ARTICLES_QUERY = gql`
  query {

   allArticles {
      title
      text
  }
  }
`;

const Home = () => {
    // Create a query hook
    const {data, loading, error} = useQuery(ARTICLES_QUERY);
  console.log(data)
    if (loading) {
        return <p>Loading...</p>;
    }

    if (error) {
        return <p>Error: {JSON.stringify(error)}</p>;
    }
    return (
        <div>
            <Head>
                <title>Home</title>
                <link rel="icon" href="/favicon.ico"/>
            </Head>
            <p>some paragraph text</p>
            <div>And something in a div</div>
            <ul>
                {data?.allArticles?.map(article => {
                    return <li key={`article__${article.title}`}>{article.title}</li>;
                })}
            </ul>
        </div>
    );
};

export default Home;

页面呈现为

enter image description here

并且该页面的页面源是
<!DOCTYPE html><html><head><style data-next-hide-fouc="true">body{display:none}</style><noscript data-next-hide-fouc="true"><style>body{display:block}</style></noscript><meta charSet="utf-8"/><meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"/><meta name="next-head-count" content="2"/><link rel="preload" href="/_next/static/development/pages/index.js?ts=1582296618319" as="script"/><link rel="preload" href="/_next/static/development/pages/_app.js?ts=1582296618319" as="script"/><link rel="preload" href="/_next/static/runtime/webpack.js?ts=1582296618319" as="script"/><link rel="preload" href="/_next/static/runtime/main.js?ts=1582296618319" as="script"/><noscript id="__next_css__DO_NOT_USE__"></noscript></head><body><div id="__next"><p>Loading...</p></div><script src="/_next/static/development/dll/dll_d6a88dbe3071bd165157.js?ts=1582296618319"></script><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{},"apolloState":{},"apollo":null},"page":"/","query":{},"buildId":"development","isFallback":false}</script><script nomodule="" src="/_next/static/runtime/polyfills.js?ts=1582296618319"></script><script async="" data-next-page="/" src="/_next/static/development/pages/index.js?ts=1582296618319"></script><script async="" data-next-page="/_app" src="/_next/static/development/pages/_app.js?ts=1582296618319"></script><script src="/_next/static/runtime/webpack.js?ts=1582296618319" async=""></script><script src="/_next/static/runtime/main.js?ts=1582296618319" async=""></script><script src="/_next/static/development/_buildManifest.js?ts=1582296618319" async=""></script></body></html>

我的静态 HTML 和动态内容都不在那里。

我在这里遗漏了一些明显的东西?是 Apollo 客户端缓存吗?关于 NextJS 应该如何工作,我是否遗漏了什么?这一切都在第一页加载 - 也就是说,我知道当您在客户端导航时它是客户端呈现的,但这应该直接来自服务器,不是吗?

对于它的值(value),pages/_app.js
import React from 'react';
import App from 'next/app';
import { ApolloProvider } from '@apollo/react-hooks';

import withData from '../util/apollo-client';

class MyApp extends App {
    render() {
        const { Component, pageProps, apollo } = this.props;
        return (
            <ApolloProvider client={apollo}>
                <Component {...pageProps} />
            </ApolloProvider>
        );
    }
}

// Wraps all components in the tree with the data provider
export default withData(MyApp)

/util/apollo-client.js
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import withApollo from 'next-with-apollo';
import { createHttpLink } from 'apollo-link-http';
import fetch from 'isomorphic-unfetch';

// Update the GraphQL endpoint to any instance of GraphQL that you like
const GRAPHQL_URL = 'http://localhost:3000/admin/api';

const link = createHttpLink({
    fetch, // Switches between unfetch & node-fetch for client & server.
    uri: GRAPHQL_URL
});

// Export a HOC from next-with-apollo
// Docs: https://www.npmjs.com/package/next-with-apollo
export default withApollo(
    // You can get headers and ctx (context) from the callback params
    // e.g. ({ headers, ctx, initialState })
    ({ initialState }) =>
        new ApolloClient({
            link: link,
            cache: new InMemoryCache()
                //  rehydrate the cache using the initial data passed from the server:
                .restore(initialState || {})
        })
);

最佳答案

我认为 ApolloClient缺少 ssrMode选项

将该选项包含在您的 withApollo 中功能如下:

例子:

// Export a HOC from next-with-apollo
// Docs: https://www.npmjs.com/package/next-with-apollo
export default withApollo(
    // You can get headers and ctx (context) from the callback params
    // e.g. ({ headers, ctx, initialState })
    ({ initialState, ctx }) =>
        new ApolloClient({
            ssrMode: Boolean(ctx),
            link: link,
            cache: new InMemoryCache()
                //  rehydrate the cache using the initial data passed from the server:
                .restore(initialState || {})
        })
);

关于javascript - NextJS SSR 可以与 Apollo 客户端一起使用吗?在第一次加载页面上检查 'view page source' 时,我看不到我的 HTML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60341199/

相关文章:

javascript - 创建可注入(inject)类(构造函数)

Javascript 锁定 css 更改显示

mysql - GraphQL - 根据参数返回计算类型

caching - 如何利用 GraphQL Apollo 缓存进行离线支持?

javascript - 如何为 Apollo 客户端指定 GraphQL 查询并获取属性中出现适当字符串的项目

swift - 将 iOS 上的 Apollo 订阅与后端使用的 Action Cable 集成到 websockets

graphql - 如何使用 Apollo 和 GraphQL 在 Nextjs 中实现 CSRF 保护

javascript - 强制 Chrome (38) 退出全屏模式

javascript - TypeScript 中的区域

graphql - GraphQL 模式的图形表示