getStaticProps在prod和dev中返回空对象(下一个v9.5.1)

时间:2020-08-08 06:09:14

标签: next.js

我遇到一个奇怪的问题。使用最新的nextjs @ 9.5.1 这是有问题的代码:

import Header from './header';
import Head from './head';
import Footer from './footer';
import { useEffect } from 'react';
import Utils from '../util/utils';
import { hostName } from '../config/variables';

function Privacy({ pageTitle, metaTitle, description, metaDescription, url }) {
    console.log("Privacy -> pageTitle", pageTitle)
    useEffect(() => {
        Utils.handleFBPixelPageView('Privacy');
    }, []);

    return (
        <div>
            <Head
                isAmpPage={false}
                pageTitle={pageTitle}
                description={description}
                url={url}
                metaTitle={metaTitle}
                metaDescription={metaDescription}
            />
            <Header isAmp={false} />
            <div className="privacy-main-panel">

            Hello there!
            </div>

            <style jsx global>{`
                .privacy-main-panel {
                    width: 1000px;
                    display: flex;
                    flex-direction: column;
                    text-align: right;
                    font-family: inherit;
                    padding-top: 20px;
                    margin: 0 auto;
                }
                h1 {
                    padding: 0;
                    margin: 5px 0;
                    line-height: 1;
                    margin-bottom: 25px;
                }
                h2,
                h3 {
                    padding: 0;
                    margin: 5px 0;
                    line-height: 1;
                }
                p {
                    margin-bottom: 10px;
                }
                ul {
                    margin: 0;
                    margin-bottom: 20px;
                }
                @media only screen and (max-width: 1000px) {
                    .privacy-main-panel {
                        width: 100vw;
                        padding: 20px;
                    }
                }
            `}</style>
            <Footer isVisibleOnMobile={true} />
        </div>
    );
}

export async function getStaticProps() {
    return {
        props: {
            pageTitle: 'text1',
            metaTitle: 'text2',
            description: 'text3',
            metaDescription: 'text4',
            url: `${hostName}/privacy`,
        },
    };
}

export default Privacy;

为什么会发生这种情况?

我尝试更改此文件中的功能顺序,还对道具进行字符串化,将返回的数据作为一个整体记录下来,而不会破坏结构,但是没有运气。

如果与此问题有关,我将使用自定义服务器和NextSeo库。

更新:

我进入了nextjs中的next-server.js文件,并记录了一些相关的值:

}renderToHTML -> pathname /privacy
result {
  components: {
    App: [Function: WrappedApp] {
      displayName: 'withRedux(f)',
      getInitialProps: [Function]
    },
    Document: [class MyDocument extends Document],
    Component: [Function: Privacy],
    buildManifest: {
      polyfillFiles: [Array],
      devFiles: [Array],
      ampDevFiles: [Array],
      lowPriorityFiles: [Array],
      pages: [Object],
      ampFirstPages: []
    },
    reactLoadableManifest: { './dev/noop': [Array] },
    pageConfig: {},
    getServerSideProps: undefined,
    getStaticProps: [AsyncFunction: getStaticProps],
    getStaticPaths: undefined
  },
  query: { _nextDataReq: undefined, amp: undefined }
}
this.renderOpts {
  poweredByHeader: true,
  canonicalBase: '',
  buildId: 'development',
  generateEtags: true,
  previewProps: {
    previewModeId: 'key',
    previewModeSigningKey: 'key',
    previewModeEncryptionKey: 'key'
  },
  customServer: true,
  ampOptimizerConfig: undefined,
  basePath: '',
  optimizeFonts: false,
  fontManifest: null,
  assetPrefix: '',
  dev: true,
  ErrorDebug: [Function: ReactDevOverlay],
  ampSkipValidation: false,
  ampValidator: [Function]
}

      components.getStaticProps:  Promise {
      {
        props: {
          pageTitle: 'text1',
          metaTitle: 'text2',
          description: 'text3',
          metaDescription: 'text4',
          url: 'http://localhost:3000/privacy'
        }
      }
    }
        query:  [Object: null prototype] {}
        params:  null
        all:  { _nextDataReq: undefined, amp: undefined }
        Privacy -> pageTitle undefined

更新2: 问题似乎出在自定义_app中:

  static async getInitialProps({ Component, ctx }) {
    const pageProps = Component.getInitialProps
        ? await Component.getInitialProps(ctx)
        : {};
    return { pageProps };
}

Component.getInitialProps未定义,因此pageProps返回一个空对象。

这是否意味着getStaticProps实际上不会在自定义应用中将道具传递给getInitialProps?

更新3: appProps和pageProps均为空:

 const pageProps = AppContext.Component.getInitialProps ? 
     await AppContext.Component.getInitialProps(AppContext.ctx)
     : {};

 console.log('MyApp -> getInitialProps -> pageProps', pageProps);

 const appProps = App.getInitialProps ? await App.getInitialProps(AppContext): {};
 console.log('MyApp -> getInitialProps -> appProps', appProps);

更新4: 这是自定义_app(如果有人想看到它,因为这可能是问题所在):

import withRedux from 'next-redux-wrapper';
import App from 'next/app';
import React from 'react';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import Amplify from 'aws-amplify';
import ReactPixel from 'react-facebook-pixel';
import Router from 'next/router';
import withGA from 'next-ga';
import * as Sentry from '@sentry/browser';
import MobileBarController from '../components/mobile-bar-controller';
import rootReducer from '../store/reducers/root-reducer';
import { userLogin } from '../store/actions/actions';
import Utils from '../util/utils';
import {
    apiUrl,
    facebookPixelId,
    sentryDsnFrontend,
} from '../config/variables';


const makeStore = (initialState, options) => {
    return createStore(rootReducer, initialState);
};

Amplify.configure({
    Auth: {
        identityPoolId: 'id',
        region: 'region',
    },
    API: {
        graphql_endpoint: apiUrl,
        region: 'region',
        identityPoolId: 'poolId',
    },
    bucket: 'items-bucket',
});

Sentry.init({
    dsn: `${sentryDsnFrontend}`,
});
class MyApp extends App {
    constructor(props) {
        super(props);
        if (!Utils.isServer()) {
            let user = Utils.getCookieAsJson('persist:user');
            let token = Utils.getCookie('user_token');
            if (user && token) {
                props.store.dispatch(userLogin(user, token));
            }
        }
    }
    static async getInitialProps({ Component, ctx }) {
        if (
            Utils.isServer() &&
            ctx &&
            ctx.req &&
            ctx.req.headers &&
            ctx.req.headers.cookie
        ) {
            let cookie = ctx.req.headers.cookie;
            if (cookie) {
                let cookies = cookie.split(';');
                let user = null;
                let token = null;

                for (let i = 0; i < cookies.length; i++) {
                    if (cookies[i].indexOf('persist:user') > -1) {
                        user = JSON.parse(
                            unescape(cookies[i].replace('persist:user=', ''))
                        );
                    } else if (cookies[i].indexOf('user_token') > -1) {
                        token = cookies[i].replace('user_token=', '');
                    }
                }
                if (user && token) {
                    ctx.store.dispatch(userLogin(user, token));
                }
            }
        }
        const pageProps = Component.getInitialProps
            ? await Component.getInitialProps(ctx)
            : {};
        return { pageProps };
    }

    componentDidMount() {
        ReactPixel.init(
            facebookPixelId,
            {},
            { debug: false, autoConfig: false }
        );
    }

    componentDidCatch(error, errorInfo) {
        Sentry.withScope((scope) => {
            Object.keys(errorInfo).forEach((key) => {
                scope.setExtra(key, errorInfo[key]);
            });

            Sentry.captureException(error);
        });

        super.componentDidCatch(error, errorInfo);
    }

    render() {
        const { Component, pageProps, store } = this.props;
        return (
            <Provider store={store}>
                <Component {...pageProps} />
                <MobileBarController />
            </Provider>
        );
    }
}

export default withRedux(makeStore)(withGA('GA-ID', Router)(MyApp));

更新5: 您可以在这里找到一个副本: https://github.com/omar-dulaimi/nextjs-no-staticprops-repro

1 个答案:

答案 0 :(得分:1)

因此,基本上,该问题与next-redux-wrapper软件包有关。它是在最新的Nextjs功能之后更新的,因此当我将项目更新到v9.5.1时,getStaticProps无法正常工作,因为我从未升级过next-redux-wrapper版本或配置。

希望这可以节省将来的时间。正如Nextjs贡献者所建议的,此示例在此处https://github.com/vercel/next.js/tree/canary/examples/with-redux-wrapper