I'm working on my first serious NextJS app. I have it set up to pull in JSON data for the left nav, rather than hardcoding them in the app somewhere. This way I don't have to rebuild every time there's a minor change to the site's navigation.
Since the navigation needs to be available on every page, I added getInitialProps
to the _app.js
file, which grabs the left nav and passes it to the left nav ponent. But now as I'm moving on to build the homepage, I see that the getInitialProps
there does not run. It seems that the getInitialProps
in _app.js
takes precendence.
Is there a way to have both? Or some other workaround that acplishes the goal (or just a better way to do this in general)?
Note that I'm using getInitialProps
for two reasons:
- getStaticProps is out because I don't plan to build the entire site at build time
- getServerSideProps is usually out because I don't like that it ends up doing two http requests: first a request goes to the
NextJS
server, then the server sends a request to my API (which happens to live on a different server). If I'm just getting basic stuff like the navigation, there's no need forgetServerSideProps
to run on theNextJS
server, I'd rather skip the middle man
Here's some some simplified code:
_app.js:
import { Provider } from "react-redux";
import axios from "axios";
import store from "../store";
import Header from "../ponents/Header";
import LeftNav from "../ponents/LeftNav";
function MyApp(props) {
const { Component, pageProps } = props;
return (
<Provider store={store}>
<Header />
<LeftNav leftnav={props.leftnav} />
<Component { ...pageProps } />
</Provider>
)
}
MyApp.getInitialProps = async (context) => {
let config = await import("../config/config");
let response = await axios.get(`${config.default.apiEndpoint}&cAction=getLeftNav`);
if (response) {
return {
leftnav: response.data.leftNav
};
} else {
return {
leftnav: null
};
}
};
export default MyApp;
Home.js:
import axios from "axios";
const Home = (props) => {
console.log("Home props", props);
return (
<div>home</div>
);
};
Home.getInitialProps = async(context) => {
// this only runs if the getInitialProps in _app.js is removed :(
let config = await import("../config/config");
let response = await axios.get( `${config.default.apiEndpoint}&cAction=getHome` );
if ( response ) {
return {
home: response.data.home
};
} else {
return {
home: null
}
}
};
export default Home;
I'm working on my first serious NextJS app. I have it set up to pull in JSON data for the left nav, rather than hardcoding them in the app somewhere. This way I don't have to rebuild every time there's a minor change to the site's navigation.
Since the navigation needs to be available on every page, I added getInitialProps
to the _app.js
file, which grabs the left nav and passes it to the left nav ponent. But now as I'm moving on to build the homepage, I see that the getInitialProps
there does not run. It seems that the getInitialProps
in _app.js
takes precendence.
Is there a way to have both? Or some other workaround that acplishes the goal (or just a better way to do this in general)?
Note that I'm using getInitialProps
for two reasons:
- getStaticProps is out because I don't plan to build the entire site at build time
- getServerSideProps is usually out because I don't like that it ends up doing two http requests: first a request goes to the
NextJS
server, then the server sends a request to my API (which happens to live on a different server). If I'm just getting basic stuff like the navigation, there's no need forgetServerSideProps
to run on theNextJS
server, I'd rather skip the middle man
Here's some some simplified code:
_app.js:
import { Provider } from "react-redux";
import axios from "axios";
import store from "../store";
import Header from "../ponents/Header";
import LeftNav from "../ponents/LeftNav";
function MyApp(props) {
const { Component, pageProps } = props;
return (
<Provider store={store}>
<Header />
<LeftNav leftnav={props.leftnav} />
<Component { ...pageProps } />
</Provider>
)
}
MyApp.getInitialProps = async (context) => {
let config = await import("../config/config");
let response = await axios.get(`${config.default.apiEndpoint}&cAction=getLeftNav`);
if (response) {
return {
leftnav: response.data.leftNav
};
} else {
return {
leftnav: null
};
}
};
export default MyApp;
Home.js:
import axios from "axios";
const Home = (props) => {
console.log("Home props", props);
return (
<div>home</div>
);
};
Home.getInitialProps = async(context) => {
// this only runs if the getInitialProps in _app.js is removed :(
let config = await import("../config/config");
let response = await axios.get( `${config.default.apiEndpoint}&cAction=getHome` );
if ( response ) {
return {
home: response.data.home
};
} else {
return {
home: null
}
}
};
export default Home;
Share
Improve this question
asked Jun 30, 2021 at 21:57
Mike WillisMike Willis
1,52216 silver badges37 bronze badges
1 Answer
Reset to default 8You have to call App.getInitialProps(context)
in your _app
to call the current page's getInitialProps
. You can then merge the page's props with the remaining props from _app
.
import App from 'next/app'
// Remaining code...
MyApp.getInitialProps = async (context) => {
const pageProps = await App.getInitialProps(context); // Retrieves page's `getInitialProps`
let config = await import("../config/config");
let response = await axios.get(`${config.default.apiEndpoint}&cAction=getLeftNav`);
return {
...pageProps,
leftnav: response?.data?.leftNav ?? null
};
};
From the custom _app
documentation:
When you add
getInitialProps
in your custom app, you mustimport App from "next/app"
, callApp.getInitialProps(appContext)
insidegetInitialProps
and merge the returned object into the return value.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744084557a4555924.html
评论列表(0条)