编辑:因为我没有打电话给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;
页面呈现为
并且该页面的页面来源是
<!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应该如何工作,我是否缺少某些东西?这一切都是在第一页加载上完成的-也就是说,我知道当您在客户端上导航时它是在客户端上呈现的,但这应该直接来自服务器,不是吗?
对于它的价值,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 || {})
})
);