gpt4 book ai didi

javascript - NextJS官方示例代码: _app. getInitialProps调用Component.getInitialProps——这是为了确保所有页面都加载数据吗?

转载 作者:行者123 更新时间:2023-12-01 01:19:27 25 4
gpt4 key购买 nike

我试图了解如何将 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' />
}
}

this getInitialProps 会等到所有数据加载完毕后才返回吗?它如何知道它何时加载?

非常感谢任何帮助!

最佳答案

  1. 由于 _app.js 是一个 HoC,因此您在 _app.js 内的组件基本上是您想要从页面文件夹加载的页面(如果您进一步编写,您可以传播另一个 HoC,然后加载您的页面,具体取决于您的应用程序,但是在您的 compose HoC 中,您必须再次实现 getInitialProps,然后执行最终 page.js 的 getInitialProps)。每个页面都可以有一个自己的 getInitialProps(例如,在您的联系页面上,您想要加载您的公司地址,并且仅在整个应用程序中加载)。 _app.js 执行 Component.getInitProps(如果设置)。如果组件的方法返回一个非空对象,它将成为您最终在渲染方法内提供给组件的 pageProps。

  2. 您的 page.js 现在已实现 getInitProps 方法,该方法会分派(dispatch) saga 任务并返回 isServer ...鉴于此,只有您的存储通过分派(dispatch)操作进行水合 - getInitProps 不必等待任何事情并返回一个 bool 值。商店水合后,您的组件将被更新,因为商店中的 Prop 已加载/更新。

但是我现在面临同样的问题:

我在 getInitProps 中调度 saga 任务,但由于操作是异步的,我在 ComponentDidMount 之后收到 Prop 。

编辑:

Link to read

TL:博士;

  • Saga 任务是线程,或者如果您想要一种事件监听器。
  • 每次您发送 saga 操作(取决于您的 sagas)时,都会启动一个监听器
  • 在我们的例子中,如果我们在 getInitialProps 中触发一个操作,我们会使用 saga 任务将操作分派(dispatch)到 store,但是 store.dispatch 方法不是异步 => 这导致 getInitialProps 不会被该操作阻止并立即返回 props触发的任务尚未完成
  • Victor 的解决方案以及 next-redux-saga 包中的解决方案是 1. 调度“END”操作以停止当前根任务,2. 应用 toPromise() 方法,该方法使您能够异步等待让传奇故事结束。 => 您可以阻止 getInitialProps 并强制该方法在方法返回之前等待传奇结束;
  • 重要提示:当您停止 saga 线程时,这是可以的,并且必须/应该在服务器上完成,但是您的应用程序需要客户端上的 sagas 来正确处理存储副作用,因此如果 !isServer,则必须重新运行 sagas。

更新:

这不起作用。您只能停止服务器上的 sagas,因为您只需要它们在初始执行时,服务器上的 sagas 之后就几乎没有用了。然而在客户端你无法阻止这些传奇。

这是我的 store.js...您可以执行初始传奇,服务器将等待它们在 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();
}
};

关于javascript - NextJS官方示例代码: _app. getInitialProps调用Component.getInitialProps——这是为了确保所有页面都加载数据吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54367390/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com