NextJS:将json加载到_app.js vs页面中的getInitialProps中并避免重复调用

时间:2019-08-26 16:42:25

标签: reactjs redux next.js

我已经使用getInitialProps将大型json文件加载到单个页面上。由于它是一个很大的json,我想知道如何将其加载到索引页面上。仅当有人直接绕过索引进入子页面且该子页面不在道具中时,子页面才应加载该页面。与单个组件相比,文档在加载到_app时有些混乱。另外,如果道具已经被获取,则不清楚如何在getInitialProps内进行检查...

import App from 'next/app'
import React from 'react'
import withReduxStore from '../store/with-redux-store'
import { Provider } from 'react-redux'
import "isomorphic-fetch"

class MyApp extends App {
  static async getInitialProps({ Component, ctx }) {
    let res = await fetch('https://xxxx.json', { mode: 'no-cors' });
    let productParams = await res.text().then((data) => {
      return (data ? JSON.parse(data) : {})
    })
      .catch((error) => {
        console.error("Something bad happened", error);
      });
    console.log(`Show data fetched. Count: ${Object.keys(productParams).length}`);
    return { productParams, topState: "loaded" }
  }

  render() {
    return (
      <Provider store={reduxStore}>
        <Component {...this.props} />
      </Provider>
    )
  }
}

export default withReduxStore(MyApp)


________________________________________________


class SubPage extends React.Component {

  static async getInitialProps({ reduxStore, topState }) {
    reduxStore.dispatch(loadInitialState());

    if (topState != "loaded") {
      let res = await fetch('https://xxxxxx.json', { mode: 'no-cors' })
      let productParams = await res.json();
      return { productParams }
     } else {
    return {}
     }
  }
  state = { ...this.props, riskType: "xxx" }

  componentDidMount() {
    console.log(this.state);
  }

  render() {
    return (
      <Layout>
       <SubComponent />
      </Layout>

    )
  }
}


const mapStateToProps = (state) => {
  return state;
};

const mapDispatchToProps = (dispatch) => {
  return {
    loadInitialState: () => {
      dispatch({ type: "LOAD_INITIAL_STATE" });
    }
  };
};



export default connect(
  mapStateToProps,
  mapDispatchToProps
)(SubPage)

如果我转到主页,_app将加载json,然后如果我单击子页面链接,则它不再位于道具中。仅当我重新加载子页面时,它才会再次出现在道具中。我在做什么错了?

1 个答案:

答案 0 :(得分:0)

据我所知,您的示例似乎有几个问题。但是需要解决的主要问题是:

    Component上的
  1. _app.js实际上是传递给您的MyApp组件的道具。
  2. 由于要覆盖它,因此应在静态App.getInitialProps内部调用MyApp.getInitialProps。实际上,这将触发对页面自己的getInitialProps的调用。
  3. getInitialProps中从_app.js返回的道具以pageProps发送到MyApp

将所有内容放在一起看起来像这样:

import App from 'next/app'

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

MyApp.getInitialProps = async (appContext) => {
   // calls page's `getInitialProps` and fills `appProps.pageProps`
   const appProps = await App.getInitialProps(appContext);

   // Fetch your json file
   const res = await fetch('https://xxxx.json', { mode: 'no-cors' });
   const productParams = await res.json();

   return { ...appProps, productParams, topState: "loaded" };
 }

export default MyApp

请记住,从您的自定义getInitialProps中设置App会强制将应用程序中的每个页面呈现为服务器端,并且完全使静态优化无效。您可以在其official documentation section上阅读有关自定义App的更多信息。