如何在redux动作中调用两个API,其中一个API调用取决于另一个API返回的内容?

时间:2019-09-03 17:38:35

标签: reactjs redux react-redux

我需要在redux动作中调用第二个API,并且该api需要使用从第一个API返回的变量。

我尝试使用.then(),但无法获取从第一个返回的数据。

export const getLoginCredential = () => dispatch => {
  fetch("http://localhost:3500/login", {
    method: "POST",
    headers: {
      "content-type": "application/json"
    },
    body: JSON.stringify({ "EID": "123", "appName":"myapp" })
  })
  .then(res => res.json())
  .then(data => {
    dispatch({
      type: LOGIN_USER,
      payload: data
    })

    let roleId;
    data.userRoleLinkDTO.map(role => {
      if (role.isDefault === "Y") {
        roleId = role.roleID;
      }
    })
    return roleId;
  })
  .then(id => {
    console.log(id);
    fetch("http://localhost:3500/", {
      method: "POST",
      headers: {
        "content-type": "application/json"
      },
      body: JSON.stringify({"data" : [{ "name": "getThings", "urlparameter": { "appId": "1", "userId": "1234", "roleID": id }, "parameter": "" }]})
    })
  })
  .then(res => res.json())
  .then(data => dispatch({
    type: FETCH_ROLE_MENU,
    payload: data
  }))
  .catch(err => console.log(err))
}

在我的第二个API调用中,我想使用我想从中返回的roleId .then(data => { dispatch({ type: LOGIN_USER, payload: data }) })

1 个答案:

答案 0 :(得分:0)

您已经发现,调度的动作不能可靠地返回您的期望。虽然不一定是这种情况,但我从不使用动作的返回值。您可以做的是创建一个新操作,该操作会在您的第一个呼叫中接受roleId。从技术上讲,您可以在一个函数中执行此操作,但是我认为这在逻辑上是合理的。

与此类似的事情应该可以满足您的需求。

const fetchUserRole = ({roleId}) => dispatch => {
  fetch("http://localhost:3500/", {
    method: "POST",
    headers: {
      "content-type": "application/json"
    },
    body: JSON.stringify({ "data": [{ "name": "getList", "urlparameter": { "appId": "1", "someId": "555", "roleID": roleId }, "parameter": "" }] })

  })
    .then(res => res.json())
    .then(data => dispatch({
      type: FETCH_ROLE_MENU,
      payload: data
    }))
}

export const getLoginCredential = () => dispatch => {
  fetch("http://localhost:3500/login", {
    method: "POST",
    headers: {
      "content-type": "application/json"
    },
    body: JSON.stringify({ "EID": "444", "appName": "my-project.com" })

  })
    .then(res => res.json())
    .then(data => {
      dispatch({
        type: LOGIN_USER,
        payload: data
      })
      const roleId = getLastMatchingRoleId(data) // line added from your clarification
      dispatch(fetchUserRole({ roleId }))
    })
}

仅供参考,您没有包括roleId的来源。我假设您正在处理样品中未显示的地方。

更新: 您的实现似乎只是试图在数组中找到与role.isDefault === "Y"匹配的条目的最后一个实例,以获取roleId。这只是算法上的挑战,与redux无关。

Array#map用于创建数组的新实例。 Array#forEach是专为您的用例设计的枚举。

我的建议是创建一个帮助函数,为您找到合适的roleId。这不是什么新鲜事。我只是采用了您现有的逻辑,将其更改为使用beforeEach(适当的枚举)并变成了函数。

function getLastMatchingRoleId(data) {
  let roleId;
  data.userRoleLinkDTO.beforeEach(role => {
    if (role.isDefault === "Y") {
      roleId = role.roleID;
    }
  })
  return roleId;
}

您需要做的就是将其合并到我现有的答案中(我已经在上面更新了)