Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Next.js. How to call component's getInitialProps in Layout

I add header component to layout but i don't want to send props from layout to header for every page I want use getInitialProps

layout.js

import Header from './header'
export default ({title}) => (
      <div>
        <Head>
          <title>{ title }</title>
          <meta charSet='utf-8' />
        </Head>

        <Header />

        {children}
      </div>
    )

header.js

export default class Header extends Component {
    static async getInitialProps () {
      const headerResponse = await fetch(someapi)
      return headerResponse;
    }
    render() {
        console.log({props: this.props})
        return (
            <div></div>
        );
    }
}

console: props: {}

App.js

  import Layout from './layout'
  import Page from './page'
  import axios from 'axios'

const app =  (props) => (
  <Layout >
    <Page {...props}/>
  </Layout>
)

app.getInitialProps = async function(){
  try {
    const response = await axios.get(someUrl)
    return response.data;

  } catch(e) {
    throw new Error(e);
  }
}

export default app

I want to use get initial props in Header component but it not firing

like image 687
Aliaga Aliyev Avatar asked Dec 06 '18 12:12

Aliaga Aliyev


People also ask

How do I use getInitialProps in NextJS?

getInitialProps is used to asynchronously fetch some data, which then populates props . Data returned from getInitialProps is serialized when server rendering, similar to what JSON. stringify does. Make sure the returned object from getInitialProps is a plain Object and not using Date , Map or Set .

How do I redirect in getInitialProps?

Solution #1: getInitialProps() To do a quick recap, getInitialProps() is a function/method that lets you write server code before the page component in Next. JS gets rendered. In that function/method you can redirect a user to an internal or external URL via the server side.

Is getInitialProps deprecated?

Addition of getServerSideProp and getServerSideProp is greatly desirable, since getInitialProps will be deprecated and most likely deleted from next.

How do I use multiple layouts in NextJS?

If you need multiple layouts, you can add a property getLayout to your page, allowing you to return a React component for the layout. This allows you to define the layout on a per-page basis. Since we're returning a function, we can have complex nested layouts if desired.


1 Answers

EDIT: 2021 way of doing this :

// with typescript remove type if you need a pure javascript solution
// _app.tsx or _app.jsx
import type { AppProps } from 'next/app';

import Layout from '../components/Layout';

export default function App({ Component, pageProps }: AppProps) {

  return (
    <Layout {...pageProps}>
      <Component {...pageProps} />
    </Layout>
  );
}

// In order to pass props from your component you may need either `getStaticProps` or `getServerSideProps`.
// You should definitely not do that inside your `_app.tsx` to avoid rendering your whole app in SSR;
// Example for SSR
export async function getServerSideProps() {
  // Fetch data from external API
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  // Pass data to the page via props
  return { props: { data } }
}

Next.js uses the App component to initialize pages. You can override it and control the page initialization.

What you could do is, put your logic inside the _app override and pass it to your children components, example with a Layout component.

Create a page/_app.js

import React from 'react'
import App, { Container } from 'next/app'

import Layout from '../components/Layout'

export default class MyApp extends App {
  static async getInitialProps({ Component, router, ctx }) {
    let pageProps = {}
    

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx)
    }

    /* your own logic */

    return { pageProps }
  }

  render () {
    const { Component, pageProps } = this.props

    return (
      <Container>
        <Layout {...pageProps}>
          <Component {...pageProps} />
        </Layout>
      </Container>
    )
  }
}

There is a good example from zeit at github

like image 137
Fabien Greard Avatar answered Sep 28 '22 10:09

Fabien Greard