通过链接导航时,nextjs getInitialProps行为异常

时间:2019-12-11 06:29:02

标签: javascript reactjs typescript environment-variables next.js

我需要getInitialProps才能在呈现页面时立即运行服务器端,但是看来它只能在我的项目中页面的第一次呈现时运行。随后的每个渲染(例如,我跟随链接或通过Router.push( \ link )推送新路线),仅在客户端运行,而我无权访问在服务器端定义的ENV变量,例如我的GraphQL API_URL。

这是我的项目结构。

./pages
   _app.tsx
   index.tsx
   other.tsx

_app.tsx中,我有以下内容

class CustomApp extends App {
  static async getInitialProps({ Component, ctx }: AppContext) {
    let pageProps = {};

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);
    }

    return { pageProps };
  }

  render() {
    const { Component, pageProps } = this.props;

    return (
      <>
        <Head>
          <title>My cool app</title>
        </Head>
        <Component {...pageProps} />
      </>
    );
  }
}

export default CustomApp;

index.tsx

import React, { Component } from 'react';
import Router from 'next/router';

class Index extends Component {
  navigateToApplication = () => {
    Router.push('/other');
  };

  render() {
    return (
      <div style={{width:100px, height:20px, color:red}} onClick={this.navigateToApplication}>      
        Click me!
      </div>
    );
  }
}

export default Index;

other.tsx中,我有以下内容:

import React, { Component } from 'react';
import dynamic from 'next/dynamic';
import config from '../src/config';

//Ensure the WizardComponent loads CLIENT SIDE. This makes the 'fetch' utility available for the gqlClient
const WizardComponent = dynamic(() => import('../src/components/layout/WizardComponent'), { ssr: false });

class Application extends Component {
 static async getInitialProps() {
    return { config };
  }

  render() {

    return <ApplicationWizard apiUrl={config.API_URL} />;
  }
}

export default Application;

config.ts中,以下内容:

import getConfig from 'next/config';
const nextConfig = getConfig();

const clientConfig = (nextConfig && nextConfig.publicRuntimeConfigå) || {};
const settings = Object.keys(process.env).length > 1 ? process.env : clientConfig;

const config = new (class {
  constructor(private readonly settings: Record<string, string | undefined>) {
    console.log('getting details', settings);
    console.log('NODE_ENV', this.settings['NODE_ENV']);
    console.log('API_URL', this.settings['API_URL']);
  }


  readonly ENVIRONMENT = process.env.ENVIRONMENT || this.settings['NODE_ENV'] || 'development';
  readonly API_URL = process.env.API_URL || this.settings['API_URL'] || 'http://localhost:4000/graphql';
})(settings);

export default config;

next.config.js中,我有以下内容:

const pick = require('lodash/pick');
const withCSS = require('@zeit/next-css');
const withSass = require('@zeit/next-sass');
const withPlugins = require('next-compose-plugins');
const withGraphql = require('next-plugin-graphql');
const path = require('path');

const nextConfig = {        

  webpack: (config, options) => {    
    config.resolve.alias['src'] = path.join(__dirname, 'src/');      
    return config;
  }
  ,publicRuntimeConfig : pick(process.env, ['NODE_ENV', 'API_URL']) 
};

module.exports = withPlugins([withCSS, withSass, withGraphql], nextConfig);

如果我直接访问http://host.url/other,则getInitialProps方法将按预期执行。如果我通过nextjs方法导航到页面,例如Router.push<Link> HOC,然后env变量返回未定义,而我又退回到默认值...

我显然在这里缺少东西。请帮助!

我想做的就是在API_URL页面上提供环境变量other.tsx,无论我如何到达那里……

0 个答案:

没有答案