使用redux-api-middleware链接异步操作

时间:2017-10-16 11:58:22

标签: asynchronous promise redux redux-api-middleware

我有一个使用Redux,redux-thunk,react-router和redux-api-middleware的React应用程序。

为了让我的应用中的Page组件呈现,我必须访问两个API端点并将其结果存储在redux存储中。

目前,我正在同时发送这两个动作。当一个动作的结果在另一个动作之前完成时,这会导致问题。 因此,在发送第二个动作之前,我需要确保一个动作完成。

阅读完所有文档后,我无法理解如何使用redux-api-middleware实现这一目标。

这是我目前的组成部分:

class Page extends React.Component {
  static prepareState = (dispatch: Function, match: Match) => {
    const { params: { projectSlug, menuSlug, pageSlug, env } } = match
    if (!projectSlug || !env) {
      return
    }

    dispatch(getSettings(projectSlug, env))
    dispatch(getPage(projectSlug, env, menuSlug || '', pageSlug || ''))            

  }
  ...

我试过了:

class Page extends React.Component {
  static prepareState = (dispatch: Function, match: Match) => {
    const { params: { projectSlug, menuSlug, pageSlug, env } } = match
    if (!projectSlug || !env) {
      return
    }

    dispatch(
     dispatch(getSettings(projectSlug, env))
   ).then(res => {
     console.log('success', res)
     dispatch(getPage(projectSlug, env, menuSlug || '', pageSlug || ''))
   }).catch(e => {
     console.log('failure', e, menuSlug, pageSlug)
   })

  }
  ...

但这会导致调用catch而不是then。但是GET_SETTINGS_SUCCESS操作实际上已经完成了,所以我很困惑为什么要调用catch。我做错了什么?

这是动作生成器:

export const getSettings = (projectSlug: string, env: string) => (dispatch: Function, getState: Function) => {
  if (getState().settings[env] && loadCompleted(getState().settings.apiState)) {
    // already loaded
    return
  }

  dispatch({
    [CALL_API]: {
      endpoint: settingsUrl(projectSlug, env),
      method: 'GET',
      credentials: 'include',
      types: [{
        type: 'GET_SETTINGS',
        meta: {projectSlug, env}
      }, {
        type: 'GET_SETTINGS_SUCCESS',
        meta: {projectSlug, env}
      }, {
        type: 'GET_SETTINGS_FAIL',
        meta: {projectSlug, env}
      }]
    }
  })
}

1 个答案:

答案 0 :(得分:0)

创建名为getSettingsThenPage的第三个动作。

export const getSettingsThenPage = (projectSlug, env, menuSlug = '', pageSlug = '') => dispatch => {
  return dispatch(getSettings(projectSlug, env))
    .then(() => {
      return dispatch(getPage(projectSlug, env, menuSlug, pageSlug)));
    };
};

随时随地调用该操作。