【问题标题】:Redux Thunk Callback after dispatching an action?调度操作后的 Redux Thunk 回调?
【发布时间】:2016-08-20 02:07:46
【问题描述】:

所以在我的 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 is not a function

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

【问题讨论】:

  • 这有很多问题。首先,不清楚您要完成什么。此外,您分配data,然后立即检查它是否真实。它总是因为你刚刚分配它。然后updateAlert 不返回任何内容。它应该返回一个动作,或者如果你需要 redux thunk 来做某事,它应该返回一个函数。
  • 我还注意到您正在调用回调函数,但由于您的所有代码都是同步的(您无需等待任何内容),因此根本不需要回调。
  • 嘿@DDS,我继续用我的最新情况更新了这个问题。我试图在调用 this.props.updateAlert 之后从我的 React 组件启动回调,而不是在操作中启动回调。我想我越来越接近了 - 你对这个更新的代码有什么想法吗?
  • 为什么需要回调?
  • updateAlert运行完成后调用函数的正确方法是:this.props.updateAlert('hi'); theFunction();调用后运行即可。

标签: reactjs callback redux redux-thunk


【解决方案1】:

使用 redux-thunk,你可以让 action 返回一个 promise:

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 => {.....});

【讨论】:

  • 你的意思是dispatch 在第二行而不是返回
  • @Swapnil,是的。谢谢。
【解决方案2】:
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 一起使用。还需要减速器和反应组件。

在反应中,褪色不一定是一件容易的事。我建议你把它留到以后。

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

当状态发生变化时,Redux 会告诉 react 重新渲染适当的组件。大概其中一个组件会根据具体情况显示或不显示消息。

【讨论】:

  • 谢谢@DDS!我不知道你是否看到了,但我在我的要点上回复了你,我基本上只是在我调用组件中的 showAlert 道具之后立即调用了 setTimeout。在此操作中调度 showAlert 后仍然使用 redux-thunk 并设置超时是否更合适?现在只考虑最佳实践,因为它们都完成了工作。
  • 使用 redux-thunk 更干净。它将意图打包并使其可重用。此外,请确保删除之前的警报(如果有的话)。否则,如果在 5 秒内触发了两个警报,则第二个警报将被第一个 setTimeout 关闭。
【解决方案3】:

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

【讨论】:

【解决方案4】:

redux 中的动作是普通对象。 Redux thunk 允许返回函数而不是对象。这些函数由 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,
    };
  }

}

【讨论】:

    猜你喜欢
    • 2016-11-23
    • 2017-09-16
    • 2018-07-23
    • 2018-05-21
    • 2018-05-30
    • 2020-01-17
    • 2020-08-18
    • 1970-01-01
    • 2019-11-12
    相关资源
    最近更新 更多