最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Next.js - understanding getInitialProps - Stack Overflow

programmeradmin0浏览0评论

I have an app that uses next.js along with Apollo/ Graphql and i'm trying to fully understand how the getInitialProps lifecycle hook works.

The lifecycle getInitialProps in my understanding is used to set some initial props that will render server side for when the app first loads which can be used prefetch data from a database in order to help SEO or simply to enhance page load time.

My question is this:

Every time I have a query ponent that fetches some data in my ponents across my app, do I have to use getInitialProps to be sure that data will be rendered server side?

My understanding is also that getInitialProps will only work in the page index ponents (as well as in _app.js), this would mean that any ponent lower down in the ponent tree would not have access to this lifecycle and would need to get some initial props from way up at the page level and then have them passed down the ponent tree. (would be great if someone could confirm this assumption)

Here is my code:

_app.js (in /pages folder)

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 (in /pages/users folder)

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;

I have an app that uses next.js along with Apollo/ Graphql and i'm trying to fully understand how the getInitialProps lifecycle hook works.

The lifecycle getInitialProps in my understanding is used to set some initial props that will render server side for when the app first loads which can be used prefetch data from a database in order to help SEO or simply to enhance page load time.

My question is this:

Every time I have a query ponent that fetches some data in my ponents across my app, do I have to use getInitialProps to be sure that data will be rendered server side?

My understanding is also that getInitialProps will only work in the page index ponents (as well as in _app.js), this would mean that any ponent lower down in the ponent tree would not have access to this lifecycle and would need to get some initial props from way up at the page level and then have them passed down the ponent tree. (would be great if someone could confirm this assumption)

Here is my code:

_app.js (in /pages folder)

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 (in /pages/users folder)

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;
Share Improve this question asked May 16, 2019 at 21:19 red house 87red house 87 2,41512 gold badges61 silver badges110 bronze badges 2
  • 1 Some quick notes, getInitialProps works on every page, not only the index.js. - any route that is rendered by the next.js router I guess. Yes you need to pass properties manually down the tree, or use some helper like React. createContext- you can resolve graphql queries on the server side, but, yes, unfortunately you need to do that manually in getInitialProps. – Moritz Roessler Commented May 16, 2019 at 22:20
  • It's a mess, unfortunately. – Moritz Roessler Commented May 16, 2019 at 22:26
Add a ment  | 

1 Answer 1

Reset to default 7

The answer is NO

If you use Apollo with Next JS you will not have to use getInitialProps on each page to get some initial data rendered server side. The following configuration for getInitialProps is enough for all the ponents to render out with their respective queries if they have <Query> ponents in them

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 };
  }

My issue and why I wasnt seeing any server side rendering is that Heroku or Now wouldnt perform SSR with a public URL ie my-app.heroku.. To resolve this I purchased and applied a custom URL in Heroku and it worked. Along with a custom URL I had the following configuration in my Apollo config

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

This pletely resolved it and now I have SSR without the pain of having to manually set getInitialProps on each page

Hope this helps someone

发布评论

评论列表(0)

  1. 暂无评论