仅当先前的操作成功时才​​调度redux操作

时间:2017-01-25 07:36:32

标签: reactjs react-redux

情况如下:我需要调用一些API端点,传递我之前请求的身份验证令牌。问题是此令牌可能会过期,因此每次我想调用端点来检索数据时,我需要确保令牌有效并在必要时进行续订。

目前,我有一个异步操作,用于续订令牌和另一组从API检索数据的操作。

我的目标是对这两种行为进行某种方面编程/组合,例如:

renewTokenIfNeeded = ... // action that check if token has expired and renew it getData = ... // Retrieves data from API realGetData = compose(renewTokenIfNeeded, getData);

这个想法是realGetData操作检查令牌是否已过期,调用renewTokenIfNeeded并且仅当此操作成功时才​​调用getData

这有什么模式吗?感谢。

2 个答案:

答案 0 :(得分:0)

我认为您可以创建一个返回函数而不是对象的操作,并使用redux-thunk中间件。返回函数的操作不是纯粹的,您可以在操作中进行更多函数调用并执行多个调度。所以,它可能看起来像:

getData = () => async (dispatch, getState) => {
  await renewTokenIfNeeded()
  getData()
  // Any dispatches you may want to do 
}

请确保将redux-thunk中间件添加到商店,如文档链接中所述。

答案 1 :(得分:0)

您可以使用redux thunk或任何其他中间件(例如redux saga)来解决令牌问题。 Redux thunk让动作创建者返回一个函数而不是一个动作。

export function checkTokenValidity(token) {
  return (dispatch) => {
          dispatch(TOKEN_CHECK_REQUEST());
    return (AsyncAPICall)
    .then((response) => {
      dispatch(TOKEN_CHECK_SUCCESS(response.data));
    })
    .catch((err) => {
      console.log(err);
    });
  };
}

export function getData(id) {
      return (dispatch) => {
              dispatch(GETDATA_REQUEST());
        return (AsyncAPICall(id))
        .then((response) => {
          dispatch(GETDATA_SUCCESS(response.data));
        })
        .catch((err) => {
          console.log(err);
        });
      };
    }

export function checkTokenAndGetData(token,id) {
  return (dispatch) => {
     dispatch(checkTokenValidity(token)).then(() => {
       dispatch(getData(id));
     });
  };
}

这种方法的问题在于代码变得容易混乱,因为每次都必须结合Token和任意API调用的检查。

这好一点。

(2)(如果你想在你的动作创建者中调用它进行状态跟踪)在请求中传递令牌,有一个中间件拦截请求并将响应更改为“无效令牌/过期令牌”,或者真实数据,以获得干净,可读的前端代码。

export function getData(token,id) {
      return (dispatch) => {
              dispatch(GETDATA_REQUEST());
        return (AsyncAPICall(id))
        .then((response) => {
           //if response is EXPIRED token
           dispatch(renewToken()); // renew token is another action creator
           //else
          dispatch(GETDATA_SUCCESS(response.data));
        })
        .catch((err) => {
          console.log(err);
        });
      };
    }

我的建议是在你的后端移动你的令牌验证。

(3)始终在请求中传递令牌,使用中间件拦截请求,如果已过期,则在后端代码中续订。在响应中添加一个已过期的标识符并将其更新。更简单。