Redux,Fetch,如何捕获 json()

Posted

技术标签:

【中文标题】Redux,Fetch,如何捕获 json()【英文标题】:Redux, Fetch, How to catch json() 【发布时间】:2016-10-30 01:07:40 【问题描述】:

我使用的 Web API 将返回 400 以表示无效的登录尝试。当用户尝试使用错误的凭据登录时,api 将返回如下内容:


    "non_field_errors": "Invalid credentials. Please try again".

我想要实现的是:当响应为 400 时,它应该返回 json 并使用dispatch(loginUserFailure(error)) 调度它。当然,如果成功的话,应该是dispatch(loginUserSuccess(json))。就我而言,如果.then(json => ... 可以访问响应对象,那将非常方便,但显然这是不可能的。

有关解决此问题的任何想法或有关外观的任何建议都会很棒!

export function loginUser(username, password) 

  const options = 
    method: 'POST',
    headers: 
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    ,
    body: JSON.stringify(username, password)
  ;

  return (dispatch, getState) => 
    return fetch('/api/accounts/login/', options)
      .then(response => 
        if (!response.ok) 
          throw Error(response.statusText);
        
        return response.json();
      )
      .then(json => 
        // Check the response status here and dispatch respectively
        // if (response.status !== 400) 
        //   dispatch(loginUserFailure(error));
        // 
        dispatch(loginUserSuccess(json));
      )
      .catch(error => 
        dispatch(loginUserFailure(error));
      );
  ;
;

【问题讨论】:

为什么不直接使用if (response.status !== 400) return response.json().then(loginUserSuccess).then(dispatch) @Bergi 你会说这样的做法是正确的吗? pastebin.com/C2Bn65hd 是的,没错,不过您可能想throw the json as an error 以避免重复dispatch(loginUserFailure(…)) 就是这样!根据您的建议,我认为这正是我所需要的。如果您想复制粘贴答案,请随时从更新的 pastebin pastebin.com/pGQFCht0@Bergi 中获取答案,谢谢! 【参考方案1】:

您可以手动rejectpromises,如果返回无效的响应代码,它会派上用场。这将由catch 回调处理。

The MDN 有更多关于Promise.reject() 的信息。

这个例子展示了它是如何做到的:

function status(response)   
  if (response.status >= 200 && response.status < 300)   
    return Promise.resolve(response)  
   else   
    return Promise.reject(new Error(response.statusText))  
    


function json(response)   
  return response.json()  


fetch('users.json')  
  .then(status)  
  .then(json)  
  .then(function(data)   
    console.log('Request succeeded with JSON response', data);  
  ).catch(function(error)   
    console.log('Request failed', error);  
  );

Source, section Chaining Promises

【讨论】:

另外Fetch.response 对象有一个ok 属性可以帮助你定义你是否拒绝它。【参考方案2】:

使用 window.fetch API 对您来说似乎非常低级,因为它旨在处理任何类型的响应,但您只需要 JSON。

考虑使用 axios 或其他库,它会为您处理 JSON 解析。

【讨论】:

以上是关于Redux,Fetch,如何捕获 json()的主要内容,如果未能解决你的问题,请参考以下文章

我如何在 fetch 调用中解析简单的 json 响应

如何使用 Redux Thunk 处理 fetch() 响应中的错误?

如何在使用同构获取的异常处理承诺后解析 json

使用 redux-saga 和 fetch 自动处理 401 响应

从 fetch 中检索数据 [关闭]

将异步操作分派到 redux-saga 后如何捕获 redux 存储中的更改