【问题标题】:Next.js - understanding getInitialPropsNext.js - 理解 getInitialProps
【发布时间】:2019-10-04 05:10:43
【问题描述】:

我有一个使用 next.js 和 Apollo/Graphql 的应用程序,我正在尝试完全了解 getInitialProps 生命周期挂钩的工作原理。

在我的理解中,生命周期getInitialProps 用于设置一些初始道具,这些道具将在应用程序首次加载时呈现服务器端,可用于从数据库中预取数据以帮助 SEO 或只是提高页面加载时间.

我的问题是这样的:

每次我有一个 query 组件,它会在我的 我的应用程序中的组件,我是否必须使用getInitialProps 确定数据将在服务器端呈现?

我的理解是,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;

【问题讨论】:

  • 一些快速注释,getInitialProps 可以在每个页面上工作,而不仅仅是 index.js。 - 我猜是由 next.js 路由器渲染的任何路由。是的,您需要手动将属性传递到树中,或者使用像 React. createContext 这样的帮助程序 - 您可以在服务器端解析 graphql 查询,但是,是的,不幸的是,您需要在 getInitialProps 中手动执行此操作。
  • 很遗憾,一团糟。

标签: javascript reactjs graphql next.js isomorphic-javascript


【解决方案1】:

答案是否定的

如果您将 Apollo 与 Next JS 一起使用,您将不必在每个页面上使用 getInitialProps 来获取一些在服务器端呈现的初始数据。 getInitialProps 的以下配置足以让所有组件在其中包含 &lt;Query&gt; 组件时通过各自的查询呈现出来

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 不会使用公共 URL 执行 SSR,即 my-app.heroku.com。为了解决这个问题,我在 Heroku 中购买并应用了一个自定义 URL,它起作用了。除了自定义 URL,我的 Apollo 配置中还有以下配置

  const request = (operation) => {
    operation.setContext({
      fetchOptions: {
        credentials: 'include'
      },
      headers: { cookie: headers.cookie }
    });
  }; 

这完全解决了它,现在我有了 SSR,无需在每个页面上手动设置 getInitialProps

希望这对某人有所帮助

【讨论】:

    猜你喜欢
    • 2019-10-12
    • 2019-03-01
    • 2020-06-22
    • 1970-01-01
    • 2020-04-24
    • 2021-03-14
    • 2020-05-31
    • 2020-02-04
    • 1970-01-01
    相关资源
    最近更新 更多