Next.js - 了解 getInitialProps
Next.js - understanding getInitialProps
我有一个使用 next.js 和 Apollo/Graphql 的应用程序,我正试图完全理解 getInitialProps
生命周期挂钩的工作原理。
我理解的生命周期 getInitialProps
用于设置一些初始道具,这些道具将在应用首次加载时呈现服务器端,这些道具可用于从数据库中预取数据以帮助 SEO 或只是为了缩短页面加载时间。
我的问题是:
Every time I have a query
component that fetches some data in my
components across my app, do I have to use getInitialProps
to be
sure that data will be rendered server side?
我的理解是 getInitialProps
仅在页面索引组件中起作用(以及在 _app.js
中),这意味着组件树中较低的任何组件都不会访问此生命周期,并且需要从页面级别向上获取一些初始道具,然后将它们向下传递到组件树。 (如果有人能证实这个假设就太好了)
这是我的代码:
_app.js(在 /pages
文件夹中)
import App, { Container } from 'next/app';
import { ApolloProvider } from 'react-apollo';
class AppComponent extends App {
static async getInitialProps({ Component, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
// this exposes the query to the user
pageProps.query = ctx.query;
return { pageProps };
}
render() {
const { Component, apollo, pageProps } = this.props;
return (
<Container>
<ApolloProvider client={apollo}>
<Component client={client} {...pageProps} />
</ApolloProvider>
</Container>
);
}
}
export default AppComponent;
Index.js(在 /pages/users
文件夹中)
import React, { PureComponent } from 'react';
import { Query } from 'react-apollo';
import gql from 'graphql-tag';
const USERS_QUERY = gql`
query USERS_QUERY {
users {
id
firstName
}
}
`;
class Index extends PureComponent {
render() {
return (
<Query query={USERS_QUERY}>
{({data}) => {
return data.map(user => <div>{user.firstName}</div>);
}}
</Query>
);
}
}
export default Index;
答案是否定的
如果您将 Apollo 与 Next JS 一起使用,您将不必在每个页面上使用 getInitialProps
来获取服务器端呈现的一些初始数据。 getInitialProps
的以下配置足以让所有组件呈现出各自的查询,如果它们中有 <Query>
个组件
static async getInitialProps({ Component, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
// this exposes the query to the user
pageProps.query = ctx.query;
return { pageProps };
}
我的问题以及我没有看到任何服务器端渲染的原因是 Heroku 或 Now 不会使用 public URL 即 my-app.heroku.com 执行 SSR。为了解决这个问题,我在 Heroku 中购买并应用了一个自定义的 URL,它起作用了。除了自定义 URL 我的 Apollo 配置中还有以下配置
const request = (operation) => {
operation.setContext({
fetchOptions: {
credentials: 'include'
},
headers: { cookie: headers.cookie }
});
};
这完全解决了它,现在我有了 SSR,无需在每个页面上手动设置 getInitialProps
希望这对某人有所帮助
我有一个使用 next.js 和 Apollo/Graphql 的应用程序,我正试图完全理解 getInitialProps
生命周期挂钩的工作原理。
我理解的生命周期 getInitialProps
用于设置一些初始道具,这些道具将在应用首次加载时呈现服务器端,这些道具可用于从数据库中预取数据以帮助 SEO 或只是为了缩短页面加载时间。
我的问题是:
Every time I have a
query
component that fetches some data in my components across my app, do I have to usegetInitialProps
to be sure that data will be rendered server side?
我的理解是 getInitialProps
仅在页面索引组件中起作用(以及在 _app.js
中),这意味着组件树中较低的任何组件都不会访问此生命周期,并且需要从页面级别向上获取一些初始道具,然后将它们向下传递到组件树。 (如果有人能证实这个假设就太好了)
这是我的代码:
_app.js(在 /pages
文件夹中)
import App, { Container } from 'next/app';
import { ApolloProvider } from 'react-apollo';
class AppComponent extends App {
static async getInitialProps({ Component, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
// this exposes the query to the user
pageProps.query = ctx.query;
return { pageProps };
}
render() {
const { Component, apollo, pageProps } = this.props;
return (
<Container>
<ApolloProvider client={apollo}>
<Component client={client} {...pageProps} />
</ApolloProvider>
</Container>
);
}
}
export default AppComponent;
Index.js(在 /pages/users
文件夹中)
import React, { PureComponent } from 'react';
import { Query } from 'react-apollo';
import gql from 'graphql-tag';
const USERS_QUERY = gql`
query USERS_QUERY {
users {
id
firstName
}
}
`;
class Index extends PureComponent {
render() {
return (
<Query query={USERS_QUERY}>
{({data}) => {
return data.map(user => <div>{user.firstName}</div>);
}}
</Query>
);
}
}
export default Index;
答案是否定的
如果您将 Apollo 与 Next JS 一起使用,您将不必在每个页面上使用 getInitialProps
来获取服务器端呈现的一些初始数据。 getInitialProps
的以下配置足以让所有组件呈现出各自的查询,如果它们中有 <Query>
个组件
static async getInitialProps({ Component, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
// this exposes the query to the user
pageProps.query = ctx.query;
return { pageProps };
}
我的问题以及我没有看到任何服务器端渲染的原因是 Heroku 或 Now 不会使用 public URL 即 my-app.heroku.com 执行 SSR。为了解决这个问题,我在 Heroku 中购买并应用了一个自定义的 URL,它起作用了。除了自定义 URL 我的 Apollo 配置中还有以下配置
const request = (operation) => {
operation.setContext({
fetchOptions: {
credentials: 'include'
},
headers: { cookie: headers.cookie }
});
};
这完全解决了它,现在我有了 SSR,无需在每个页面上手动设置 getInitialProps
希望这对某人有所帮助