异步等待进入actionCreator,我应该返回结果吗?

时间:2018-06-18 12:51:25

标签: javascript reactjs redux fetch state

在我的actionCreators中,我会根据操作调用一些其他API端点,例如UPDATE_CART_ITEM等。

起初我正在使用像return axios()...这样的axios:

export const login = (username, password) => (dispatch) => {
  dispatch(requestLogin())
  const URL = `${USERS_URL}?username=${username}&password=${password}`
  return axios(URL)
    .then((response) => {
      return response.data
    })
    .then((user) => {
      dispatch(loginSuccess(user))
      // save the user on localStorage
      localStorage.setItem('user', JSON.stringify(user))
      // direct the logedin user to the games page
      history.push('/')
    })
    .catch(() => {
      return dispatch(loginFailure())
    })
}

现在我像这样使用async / await:

// On payload i have the obj: {prId: 'xxxxx'}
export const updateCartItem = (payload) => async (dispatch) => {
    const response = await fetch('cart/update',
    {
      body: JSON.stringif(payload),
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      method: 'POST',
    })

  // I m not sure if i have to return the result
  const result = await response.json()

  // I dispatch the action with the payload
  await dispatch(return {
    payload,
    type: UPDATE_CART_ITEM,
  })
} catch (err) {
  dispatch(cartActionFail(err))
}
 }

因此,在updateCartItem函数中,我该如何处理result
由于我将payload传递给reducer,似乎我不需要它。

3 个答案:

答案 0 :(得分:2)

你可能想做这样的事情:

dispatch({ payload: response, type: UPDATE_CART_ITEM })

据我所知,

dispatch(return { /*...*/ })没有意义,而且dispatch()没有回复承诺,所以没有必要等待它。

通常,如果要使用async / await替换promise链,那么您希望将foo.then(bar => { baz(bar); })替换为const bar = await foo; baz(bar);

答案 1 :(得分:1)

如果您需要立即使用您的结果,那么您应该发送UPDATE_CART_ITEM_SUCCEED之类的操作,否则什么也不做。

顺便说一句,我建议你使用redux-saga或redux-thunk来处理你的应用副作用,比如API调用。

答案 2 :(得分:1)

如果您为您的动作创建者使用相同的有效负载,如果您的后端出现问题会发生什么?你的后端不会发生变化,但是你的状态不会意识到这一点,并用有效载荷更新自己。这就是为什么你应该在这里使用一些错误检查。另外,我个人将最后的结果作为有效载荷用于我的动作创建者,而不是原始有效载荷。

export const updateCartItem = payload => async ( dispatch ) => {
  try {
    const response = await fetch(
      "cart/update",
      {
        body: JSON.stringif( payload ),
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
        },
        method: "POST",
      }
    );
    if ( !response.ok ) { throw new Error( "response error" ); }
    const result = await response.json();
    return dispatch( {
      payload: result,
      type: UPDATE_CART_ITEM,
    } );
  } catch ( error ) {
    return dispatch( cartActionFail( error.message ) );
  }
};

您可以根据需要更改和增强此逻辑。由于@ vkarpov15指出dispatch没有明确使用return并且它没有返回一个承诺,因此你不需要等待那里。