Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getInitialProps never gets called...what am I doing wrong?

I'm new to React and Next.js, so bear with me. But I've spent three hours searching, and I cannot for the life of me figure out what I'm doing wrong here.

this.props.test doesn't output anything, even though it seems like it should output 'test'.

It's like getInitialProps is never even called.

class Example extends React.Component {

  static async getInitialProps() {
    return {
      test: 'test'
    }
  }

  render() {
    return (
      <h1>Hi {this.props.test}</h1>
    )
 } 

}
like image 896
AO Folts Avatar asked Jul 13 '18 01:07

AO Folts


2 Answers

I came here with the same problem, and my Component was in /pages so the other answers didn't really help.

My issue was that I was using a custom App (/pages/_app.js) and it had a getInitialProps in it.

It's a little vague in the documentation, but in the custom app example it does mention (emphasis mine):

Only uncomment [getInitialProps] if you have blocking data requirements for every single page in your application. This disables the ability to perform automatic static optimization, causing every page in your app to be server-side rendered.

This essentially means that if your custom _app.js has a getInitialProps method, you are telling Next.js that this is the only blocking data and every other page component can just be assumed to not have or need their own getInitialProps. If you have one anyway, it'll be ignored and that's where my problem was.

This was solved by calling the getInitialProps on the page component from inside the getInitialProps for the custom App.

// pages/_app.js
const App = ({Component, pageProps }) => (
  <React.Fragment>
    <AppHeader />
    <Component {...pageProps />
  </React.Fragment>
)

App.getInitialProps = async ({Component, ctx}) => {
  let pageProps = {}
  if(Component.getInitialProps){
    pageProps = await Component.getInitialProps(ctx)
  }
  return { pageProps }
}

// pages/home.js
const Home = ({name}) => <div>Hello world, meet {name}!</div>

Home.getInitialProps = async () => {
  return { name: 'Charlie' }
}

export default Home

I'm not sure why you can't return pageProps directly (nothing gets passed), but it seems to be something special and it's working for me now, so..

like image 106
coblr Avatar answered Nov 16 '22 02:11

coblr


Because getInitialProps only works for Pages in Next.js, the correct method for child components is componentDidMount with setState instead of props.

like image 42
AO Folts Avatar answered Nov 16 '22 02:11

AO Folts