将NextJS与异步Redux Thunks一起使用有哪些限制? (或者:NextJS如何知道如何等待异步重击完成?)

时间:2020-04-15 07:37:24

标签: javascript reactjs asynchronous redux next.js

我们有一个NextJS项目,我们在其中使用Redux Thunks(用Redux Toolkit编写)。这些是异步thunk,它们可以对API进行外部调用,执行逻辑等操作。昨天,我们意识到只有在从内部链接调用页面时才在Redux存储中工作的页面,而在将页面重新加载到内部时却没有。浏览器或立即调用。我posted about this在Stack Overflow上,但意识到这是因为尽管Redux thunk被正确调用,而reducer将数据存储在存储中,但是仅从存储中传输了 part 。服务器渲染到浏览器。

这是因为-据我所知-我正在 中从派发异步thunk

export const fetchArticle = (apolloClient, id: string) => async dispatch => {
  try {
    const result: ICurrentArticleReceivedData = await apolloClient.query({
      query: ARTICLE_QUERY,
      variables: { id }
    });
 /**
 **  'fetchRelatedArticles is another async thunk
 **/
    dispatch(fetchRelatedArticles(apolloClient, id));
    dispatch(currentArticleReceived(result?.data?.Article));
  } catch (error) {
    log(error);
    dispatch(articlesError(error.toString()));
  }
};

我将fetchRelatedArticles分派更改为简单的异步调用,并且现在一切正常。

const fetchRelatedArticles = async (apolloClient, dispatch, id: string) => {
   ...
}

export const fetchArticle = (apolloClient, id: string) => async dispatch => {
   ... 
   await fetchRelatedArticles(apolloClient, dispatch, id);

我想NextJS直到第二次调度内调度才知道要“等待”。但是后来我想知道,它怎么“完全知道”如何等待派遣?

根据this article,当您调度异步thunk时,dispatch返回一个promise,仅在完成thunk时才能解决。似乎是这种情况,因为在我们的页面中,我们有getInitialProps在其中等待初始的异步thunk调度。

Index.getInitialProps = async ({ apolloClient, store }) => {
  await store.dispatch(fetchTopics(apolloClient));
  await store.dispatch(fetchArticlesWhere(apolloClient));

但是它如何在内部/内部正常工作?据我了解,Dispatch返回创建的动作,在这种情况下,由于中间件笨拙,该动作在Redux内部被调用...在什么时候将promise返还给调用dispatch的功能?

然后NextJS 等待将存储从服务器发送到客户端,直到getInitialProps完成?

最后,如果我想拥有异步thunk分派链,那么每个[内部] await都需要做dispatch吗?因此,在上述问题中,我也可以通过仅等待第二次异步调度来解决此问题?

  try {
    const result: ICurrentArticleReceivedData = await apolloClient.query({
      query: ARTICLE_QUERY,
      variables: { id }
    });
 /**
 **  'fetchRelatedArticles is another async thunk
 **/
    await dispatch(fetchRelatedArticles(apolloClient, id));
    dispatch(currentArticleReceived(result?.data?.Article));
  } catch (error) {
    log(error);
    dispatch(articlesError(error.toString()));
  }
};

感谢您提供任何信息!

0 个答案:

没有答案