In my nextjs project, I have the Layout component that needs api call. Instead of calling api calls in every pages(./pages/*), I'd like to put the logic in some global space. I researched a bit, and it looks like overriding _app.js is the way to go indicated in nextjs documentation( https://nextjs.org/docs/advanced-features/custom-app ).
I have laid out code as below. But it doesn't seem to work.
./pages/_app.js
function MyApp({ Component, appProps, results }) {
return (
<Layout {...results}>
<Component {...appProps} />
</Layout>
)
}
MyApp.getInitialProps = async (appContext) => {
const appProps = await App.getInitialProps(appContext)
const results = await getResults() //api call
return { appProps, results }
}
./components/Layout.js
const Layout = ({ children, results }) => {
return (
<React.Fragment>
<Header/>
<div className='row col-md-8 offset-md-2'>
{JSON.stringify(results)} //results is nothing here
<div className='col-md-9'>
{children}
</div>
</div>
</React.Fragment>
)
}
./pages/index.js
...
return (
<>
{head()}
<Layout>
<div className='row col-md-12'>
{showContents()}
</div>
</Layout>
</>
)
I'm sure I'm missing some obvious things. Any help would be appreciated.
Unless you're intending to have that page return similar results every time, you should migrate your api call on the client side. Next.JS has moved away from getInitialProps in favour of getStaticProps (fetch static data), getStaticPaths (pre-render a set of static pages) and getServerSideProps (this is probably closest to getInitialProps, fetching data on the server-side). More info on next.js data fetching here: https://nextjs.org/docs/basic-features/data-fetching
Now to answer your question based on the code you provided
// index.js
<Layout> <- you're not passing any props here.
It should prop the results down like so:
// index.js
function Page({ results }){
return <Layout results={results}>Hello</Layout>
}
With the client-side example, you can do something like
import { useState } from 'react'
function useCats(){
const [cats, setCats] = useState()
useEffect(() => {
fetch('https://test.api/cats')
.then(response => response.json())
.then(_cats => setCats(_cats));
}, [])
return cats
}
// then in another component
function CatsList(){
const cats = useCats();
if(!cats){
return <p>Loading</p>
}
return <div>
{cats.map(cat => <p key={cat.id}>Cat: {cat.name}</p>)}
</div>
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.