code_Knight
code_Knight

Reputation: 281

How to fetch API at component level and prerender it in nextjs?

We need to populate the list of links in the footer component But these methods getInitialProps, getServerSideProps and getStaticProps are not getting executed in the footer component. Here is the code:

const Layout = (props) => {
    return (
        <>
            <Header />
                {props.children}
            <Footer />
        </>
    );
}
export default Layout;

--- Footer Component ---

    const Footer = ({data}) => {
    return(
        <ul>
            {data && data.map((todo,index)=>{
               return <li key={index}>
                    {todo.title}
                </li>
            })}
        </ul>
    );
}
export async function getStaticProps() {   // not working with getInitialProps and getServerSideProps as well
  const res = await fetch('https://jsonplaceholder.typicode.com/todos')
  const data = await res.json();

  return {
    props: {data}
  }
}
export default Footer;

EDIT: Footer component should not displayed in Login/Signup pages.

In the _app.js, i have passed the data as <Component {...pageProps} footerData={...data} /> but the data object is not available in Footer component.

Upvotes: 1

Views: 1535

Answers (1)

cuongdevjs
cuongdevjs

Reputation: 731

getInitialProps, getServerSideProps, and getStaticProps just only run on top of the page, not component.

If you want to run fetch on Footer, you can call fetch function on useEffect hook, or simply call fetch in one of the getInitialProps, getServerSideProps, and getStaticProps on top of the page (i.e such as _index.js) and pass down Footer by props.

You also can use getInitialsProps on top application in _app.js;

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

export default class MyApp extends App {
  static async getInitialProps ({ Component, router, ctx }) {
    let pageProps = {}
    let data = await fetch('/api');
    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx)
    }

    return {data, pageProps}
  }

  render () {
    const {Component, pageProps, data} = this.props
    return <Container>
      <Component {...pageProps} footerData={data} />
    </Container>
  }
}

and FooterComponent look like this

 export const Footer = ({data}) => {
    return(
        <ul>
            {data && data.map((todo,index)=>{
               return <li key={index}>
                    {todo.title}
                </li>
            })}
        </ul>
    );
}

on the pages except Login, Signup which need Footer component (Home/index.tsx, User/index.tsx)

export const Home = ({footerData}) = {
   return <div>
       <Header/>
       <Footer data={footerData} />
   </div>
}

Upvotes: 4

Related Questions