javascript - Can I use getInitialProps in _app.js and in pages? - Stack Overflow

I'm working on my first serious NextJS app. I have it set up to pull in JSON data for the left nav

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:

  1. getStaticProps is out because I don't plan to build the entire site at build time
  2. 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 for getServerSideProps to run on the NextJS 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:

  1. getStaticProps is out because I don't plan to build the entire site at build time
  2. 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 for getServerSideProps to run on the NextJS 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
Add a ment  | 

1 Answer 1

Reset to default 8

You 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 must import App from "next/app", call App.getInitialProps(appContext) inside getInitialProps and merge the returned object into the return value.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744084557a4555924.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信