Redux动作将另一个动作作为有效负载

时间:2019-09-11 18:15:33

标签: reactjs redux react-redux redux-actions

Redux动作A可以将动作B作为有效载荷吗?

我的用例是我试图存储每个正在进行的API请求并以以下格式显示我的api状态:

type ApiState = {
    requests: { [id: string]: AnyAction }
    hasNetwork: boolean
}

requests属性的键基本上是发起请求的操作type(例如USER_FETCH_REQUEST),值是操作(具有类型,有效载荷,元数据的整个操作)。我正在使用redux-observable过滤每个以type结尾的_REQUEST(项目约定)的操作,然后,如果匹配,则调度一个新操作,该操作接收初始api请求操作作为参数(有效负载)并使用它更新ApiState

简单的例子:

const getUser = (id: string) => ({
    type: "USER_FETCH_REQUEST",
    payload: { id }
})

const addRequest = (action: AnyAction) => ({
    type: "API_REQUEST_ADD",
    payload: action
})

// somewhere in epic pipeline ("action" is result of getUser(id))
addRequest(action)

// resulting state
{
    "requests": {
        "USER_FETCH_REQUEST": {
            type: "USER_FETCH_REQUEST",
            payload: { id }
        }
    }
}

这样,如果我的应用程序脱机并且在ApiState中有5个请求,我将在保留网络后立即调度所有这些操作(因为操作应具有所有必要的数据才能正确完成请求)。 / p>

我也正在清除_SUCCESS_CANCEL上的那些请求,并在_ERROR上具有一些自定义逻辑,但是我很好奇上述规范是否是反模式的,并且可能导致不良的应用程序状态?

1 个答案:

答案 0 :(得分:0)

记录或存储动作列表根本不是反模式。正是通过这种方式实现了Time Travel,这是Redux非常流行的用例。

但是,我认为您上面的代码似乎有点过分设计。实现相同结果的一种更简单的方法是将您的操作修改为类似这样的方式

const getUser = (id: string) => {
  const action = {
    type: "USER_FETCH_REQUEST",
    payload: { id }
  }

  add_to_request_cache(action);
  return action;
}

或者,为简化起见,写一个动作创建者,如

const actionCreator = (action: AnyAction) => {
  // Code that handles various types of actions like _REQUEST or _SUCCESS actions
  // add_to_request_cache(action);
  return action;
}

,然后通过将所有动作包装在一起来构成所有动作。