发送动作后的 Redux Thunk 回调?

Redux Thunk Callback after dispatching an action?

所以在我的 React 组件中,我有这个:

this.props.updateAlertCallback('error', ERROR_MESSAGE)

我的 updateAlertCallback 操作是:

export const updateAlert = (alert, message) => {
  return {
    type: 'UPDATE_ALERT',
    alert,
    message
  }
}

export const updateAlertCallback = (alert, message) => {
  return dispatch => {
    return dispatch(updateAlert(alert, message)).then(() => {
      console.log('Done!');
    });
  }
}

我收到以下错误:Uncaught TypeError: dispatch(...).then 不是一个函数

updateAlert 完成 运行 后记录内容的正确方法是什么?

redux 中的操作是普通对象。 Redux thunk 允许 return 函数而不是对象。这些功能由 thunk 中间件执行,最终到达 store 进行调度的最终对象是一个普通对象。下面是一个 redux thunked 动作的例子。

export default class AccountActions {

  static login(username, password) {
    return (dispatch, getStore) => {
      dispatch(AccountActions.loginRequest(username));
      fetch(apiUrls.signInUrl, {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          user: {
            email: username,
            password: password,
          }
        })
      })
      .then(response => {
        return response.json().then(responseJson => {
          return dispatch(AccountActions.loginResponse(username, responseJson.token, response.status));
        });
      })
      .catch(err => {
        console.error(err);
      });
    };
  }

  static loginRequest(username) {
    return {
      type: ActionTypes.loginRequest,
      username,
    };
  }

  static loginResponse(username, token, status) {
    return {
      type: ActionTypes.loginResponse,
      username,
      token,
      status,
    };
  }

}

Redux-thunk 就是你的答案。在您的商店代码更改

const enhancers = compose(
  window.devToolsExtension ? window.devToolsExtension() : f => f
);

const enhancers = compose(
  window.devToolsExtension ? window.devToolsExtension() : f => f,
  applyMiddleware(thunk)
);

并且您将能够在 redux 操作中使用 thunk。

参考https://github.com/gaearon/redux-thunk#installation

function showAlert(message) {
  return {
    type: SHOW_ALERT, 
    message
  };
}

function hideAlert(message) {
  return {
    type: HIDE_ALERT,
  };
}

function flashAlert(message) {
  return (dispatch) => {
    dispatch(showAlert(message));
    setTimeout(() => {
      dispatch(hideAlert());
    }, 5000);
  }
}

你需要 redux-thunk 才能工作。然后,您可以将 this.props.flashAlert('Oh noes!!!!') 与适当的 mapStateToProps 一起使用。还需要减速器和反应组件。

淡入淡出在 React 中不一定是一件容易的事情。我建议你留着以后用。

flashAlert 函数的作用是 returns 一个接受 dispatch 函数的函数。这个函数可以做各种有趣的事情,但还没有。首先这个函数被传递给 redux 的 dispatch。这种分派通常会抛出异常,因为动作必须是普通对象。但是因为你使用的是 redux-thunk,所以没问题。 Redux-thunk 将调用此函数并将其传递给来自 redux 的 dispatch 函数。现在函数将 运行,终于。它做的第一件事是调度一个通过调用 showAlert() 获得的动作。这次它是一个带有 type 属性 的对象,这使它成为一个正确的 redux 操作。大概 redux 会将这个动作传递给我们的 reducer,它会用新消息更新状态,但我们不确定,因为为简洁起见,reducer 被排除在这个答案之外。谁知道它包含什么代码。在状态更改为以某种方式显示消息后,我们执行 setTimeout()。当这个回调函数返回时,我们通过调用 hideAlert() 使用我们之前使用的相同 dispatch 函数来调度我们获得的另一个动作。我们还有它。这大概会清除状态中的消息。

Redux 会告诉 React 在状态发生变化时重新渲染适当的组件。据推测,这些组件之一将根据具体情况显示或不显示消息。

使用 redux-thunk,你可以让 action return 成为一个承诺:

export const updateAlert = (alert, message) => (dispatch, getState) => {  
  dispatch ({
    type: 'UPDATE_ALERT',
    alert,
    message
  });
  return Promise.resolve(getState());
  // or just Promise.resolve();

现在您可以调用 updateAlert(xx, xx).then(newState => {.....});