【问题标题】:Can I use getInitialProps in _app.js and in pages?我可以在 _app.js 和页面中使用 getInitialProps 吗?
【发布时间】:2021-09-13 00:58:30
【问题描述】:

我正在开发我的第一个严肃的 NextJS 应用程序。我将其设置为提取左侧导航的 JSON 数据,而不是将它们硬编码在应用程序的某个地方。这样我就不必在每次网站导航发生细微变化时都重新构建。

由于导航需要在每个页面上都可用,我将getInitialProps 添加到_app.js 文件中,该文件获取左侧导航并将其传递给左侧导航组件。但是现在当我继续构建主页时,我看到那里的getInitialProps 没有运行。似乎_app.js 中的getInitialProps 优先。

有没有办法两者兼得?或者其他一些可以实现目标的解决方法(或者一般来说只是一种更好的方法)?

请注意,我使用 getInitialProps 有两个原因:

  1. getStaticProps 已退出,因为我不打算在构建时构建整个站点
  2. getServerSideProps通常退出,因为我不喜欢它最终会执行两个 http 请求:首先一个请求发送到 NextJS 服务器,然后服务器向我的 API 发送一个请求(它恰好位于不同的服务器上)。如果我只是获得导航之类的基本内容,则无需在NextJS 服务器上运行getServerSideProps,我宁愿跳过中间人

这里有一些简化的代码:

_app.js

import { Provider } from "react-redux";
import axios from "axios";

import store from "../store";
import Header from "../components/Header";
import LeftNav from "../components/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;

【问题讨论】:

    标签: javascript next.js


    【解决方案1】:

    您必须在_app 中调用App.getInitialProps(context) 才能调用当前页面的getInitialProps。然后,您可以将页面的道具与来自_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
        };
    };
    

    来自custom _app 文档:

    在自定义应用中添加getInitialProps 时,必须在import App from "next/app" 中调用App.getInitialProps(appContext) getInitialProps 并将返回的对象合并到返回值中。

    【讨论】:

      猜你喜欢
      • 2021-06-03
      • 2017-12-05
      • 2016-06-13
      • 2017-06-19
      • 2021-06-28
      • 2013-12-15
      • 2014-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多