簡體   English   中英

NextJS官方示例代碼:_app.getInitialProps調用Component.getInitialProps-這是為了確保所有頁面都加載數據?

[英]NextJS official sample code: _app.getInitialProps calls Component.getInitialProps — is this to make sure all pages load data?

我試圖了解如何將redux-saga連接到NextJS,並遵循它們提供的示例代碼-https: //github.com/zeit/next.js 我知道可以從getInitialProps內加載數據,但是我不了解Component.getInitialProps的調用是怎么回事:

class MyApp extends App {
  static async getInitialProps({Component, ctx}) {
    let pageProps = {}
    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps({ctx})
    }

    return {pageProps}
  }

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

export default withRedux(createStore)(withReduxSaga({async: true})(MyApp))

這是否允許頁面的getIntialProps中的所有異步加載加載? 也就是說,在index.js我們有代碼

class Index extends React.Component {
  static async getInitialProps (props) {
    const { store, isServer } = props.ctx
    store.dispatch(tickClock(isServer))

    if (!store.getState().placeholderData) {
      store.dispatch(loadData())
    }

    return { isServer }
  }

  componentDidMount () {
    this.props.dispatch(startClock())
  }

  render () {
    return <Page title='Index Page' linkTo='/other' NavigateTo='Other Page' />
  }
}

這個 getInitialProps等待返回,直到所有數據加載getInitialProps 如何知道何時加載?

任何幫助,不勝感激!

  1. 由於_app.js是HoC,因此_app.js中的組件基本上就是您要從pages文件夾加載的頁面(如果進一步編寫,則可以傳播另一個HoC,然后再加載頁面,取決於您的應用程序,但隨后您的撰寫HoC必須再次實現getInitialProps,然后執行最終page.js的getInitialProps。 每個頁面都可以具有自己的getInitialProps(例如,在您要加載公司地址的聯系頁面上,並且僅在整個應用程序中存在)。 _app.js執行Component.getInitProps(如果已設置)。 如果Component的方法返回一個非空對象,則它將成為您的pageProps,您最終將其提供給render方法內的Component。

  2. 您的page.js現在實現了一個getInitProps方法,該方法將分派一個傳奇任務並返回isServer ...即給出的結果是,僅您的商店通過分派操作而處於水化狀態-getInitProps不必等待任何東西並返回一個布爾值。 商店水合后,由於將加載/更新商店中的道具,因此您的組件將被更新。

但是,目前我面臨着同樣的問題:

我在getInitProps中調度了傳奇任務,但是由於動作是異步的,因此我在ComponentDidMount之后收到了道具。

編輯:

鏈接閱讀

TL:DR;

  • Saga任務是線程,或者您想要一種事件偵聽器。
  • 每當您發出傳奇動作(取決於您的sagas)時,都會啟動一個偵聽器
  • 在我們的例子中,如果我們在getInitialProps中觸發一個動作,我們使用saga任務將動作調度到商店,但是store.dispatch方法不是async =>,這導致getInitialProps不會被該動作阻止,盡管被觸發的任務會立即返回道具還沒完成
  • Victor的解決方案以及next-redux-saga軟件包中的一種解決方案是:1.分發“ END”操作以停止當前的根任務,並且2.應用toPromise()方法,該方法使您能夠異步等待sagas結束。 =>您可以阻塞getInitialProps並強制方法在方法返回之前等待sagas結束;
  • 重要提示:停止saga線程時,可以,必須在服務器上完成/應該完成操作,但是您的應用程序需要客戶端上的sagas才能正確處理商店的副作用,因此,如果!isServer,則必須重新運行sagas。

更新:

它不起作用。 您只能停止服務器上的sagas,因為只需要它們即可進行初始執行,此后服務器上的sagas幾乎沒有用。 但是,在客戶端,您無法停止sagas。

這是我的store.js ...,您可以執行初始sagas,並且服務器會在getInitialProps中等待它們完成,因為toPromise()使異步停止。

在客戶端,您必須按照自己的方式來度過整個生命周期等...客戶端存儲的水合作用無法正常工作,正如我期望的那樣。 也許更好,因為否則您將阻止React進行渲染,這通常與React背道而馳。

  store.runSagas = () => {
    if (!store.currentSagas) {
      store.currentSagas = sagaMiddleware.run(rootSaga);
    }
  };

  store.stopSagas = async () => {
    if (store.currentSagas) {
      store.dispatch(END);
      await store.currentSagas.toPromise();
    }
  };

  store.execTasks = isServer => async (tasks = []) => {
    tasks.forEach(store.dispatch);
    if (isServer) {
      await store.stopSagas();
    }
  };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM