拦截Redux中的HTTP请求

时间:2015-10-15 13:04:15

标签: redux

许多redux示例显示直接在异步操作中发出HTTP请求;但是,这将导致所有请求共同的重复代码数量超出范围,例如:

  • 根据状态代码重试失败的请求
  • 为每个请求附加公共HTTP标头。
  • 根据响应调用其他http请求(即:oauth令牌刷新)
  • 在路线转换中中止正在进行的请求。

我的直觉是,可以使用中间件来发出http请求(与redux-api-middleware相同),这可以保持store中的正在进行的请求 - 但是我也想知道如果我依靠糟糕的习惯 - 有点复制是为了支付不可变性而付出的小代价吗?

4 个答案:

答案 0 :(得分:8)

您的动作创建者只是JavaScript函数。

如果多个函数之间存在重复,则将公共代码提取到另一个函数中。这没什么不同。不要复制代码,而是将公共代码提取到函数中,然后从您的操作创建者处调用它。

最后,可以使用自定义中间件抽象出这种模式。查看Redux仓库中的“真实世界”示例,了解它是如何完成的。

答案 1 :(得分:2)

除了中止之外的所有操作都可以通过使用请求工厂来保持不可变,该工厂在返回请求之前将.then.catch(或等效,取决于承诺风味)附加到请求。

答案 2 :(得分:1)

你可以有一个执行其操作的动作,另外它调用另一个动作,要实现这一点,你需要有一个redux-async-transitions,示例代码如下所示

function action1() {
 return {
  type: types.SOMEFUNCTION,
  payload: {
   data: somedata
  },
  meta: {
   transition: () => ({
    func: () => {
     return action2;
    },
    path : '/somePath',
    query: {
     someKey: 'someQuery'
    },
    state: {
     stateObject: stateData
    }
   })
  }
 }
}

这里是异步调用

function asynccall() {
 return {
  types: [types.PENDINGFUNCTION, types.SUCCESSFUNCTION, types.FAILUREFUNCTION],
  payload: {
   response: someapi.asyncall() // only return promise
  }
  meta: {
   transition: (state, action) => ({
    onPending: () => {
    },
    onSuccess: (successdata) => {
     //gets response data can trigger result based on data
    },
    onFail: (promiseError) => {
     //gets error information used to display messages
    }
   })
  }
 }
}

答案 3 :(得分:0)

在中间件中调用http请求与在动作创建者中调用它是一样的坏主意。您应该专注于使我们的reducer足够强大,以处理异步效果以及同步状态转换。我在使用redux时找到的最好的方法是在reducer中描述效果(http请求是效果),然后使用像redux-loopredux-saga

这样的库来处理它

为了避免代码重复,您可以提取公共代码来请求功能并使用它来处理http效果