React/Redux 链接第二个 API 请求和调度

React/Redux chaining a second API request and dispatch

还在适应中。

我已经检查了问题 and ,但我仍然对如何解决这个问题感到不自在。这些在我看来都不是很清楚。

基本上我点击了 "Login" 按钮并请求了 JWT 登录令牌并成功收到了它。我注意到的是,此时我可以下载那些很少更改的列表,例如 states 或 suburbs/postcodes,这些列表很大(后者)并且应该供水疗中心立即使用,而不是将其附加到客户的呼叫中。

我想在成功收到令牌后立即对这些列表执行 API 调用并将它们存储在本地存储中。没有 "event" 它应该在成功检索 JWT 后立即触发...

这是在 React 中检索 JWT 的操作:

export const requestLoginToken = (username, password) =>
  (dispatch, getState) => {
    dispatch({type: REQUEST_LOGIN_TOKEN, payload: username})

    const payload = {
      userName: username,
      password: password,
    }

    const task = fetch('/api/jwt', {
      method: 'POST',
      body: JSON.stringify(payload),
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      },
    })
      .then(handleErrors)
      .then(response => response.json())
      .then(data => {
        dispatch({type: RECEIVE_LOGIN_TOKEN, payload: data})
        saveJwt(data)
      })
      .catch(error => {
        clearJwt()
        dispatch({type: ERROR_LOGIN_TOKEN, payload: error.message})
      })
    addTask(task)
    return task
  }

我相信添加第二个 API 调用的位置会在 "saveJwt()" 之后,但是如何。

Do/can 我把它发送到应用程序另一部分的另一个 export const action/function?

如果我写类似这样的东西,并把函数名和参数 "JWT" 放在一起,例如

.then(retrieveSelectData)

它将使用该导出功能转到那个单独的文件夹并在应用调度的同时执行 API 调用...然后 return..

有人可以概述一下这是否是将两个 API 调用作为一个调用的正确合理方法。我仍然需要获取 JWT(并在第二个中使用它),所以如果没有第一个,我就无法进行第二个调用。

如果我正确理解你的目标,你需要的是一个中间件,它将捕获所有 actions 在 reducer 捕获它们之前调度的并且可以接受 functions 和持有对调度员的引用。
请注意 reducers 只能接受 actions 是普通对象而不能接受函数。

进入 redux-thunk,一个仅用 11 行代码就可以做到这一点(以及更多)的中间件。
它捕获所有动作(在 reducer 之前)并检查是否 action === 'function'.
如果它是一个 function 那么它会调用那个 function 并将 dispatch 作为参数。
如果它不是函数,它将不理会它并让 reducers 完成它们的工作。

像这样:

function loadSomeThings() {
    return dispatch => {
        fetchFirstThingAsync.then(data => { // first API call
            dispatch({ type: 'FIRST_THING_SUCESS', data }); // you can dispatch this action if you want to let reducers take care of the first API call
            return fetchSecondThingAsync(data), // another API call with the data received from the first call that returns a promise
        })
        .then(data => {
             dispatch({ type: 'SECOND_THING_SUCESS', data }); // the reducers will handle this one as its the object they are waiting for
        });
    };
}