【问题标题】:Fail catching a promises in react未能在反应中获得承诺
【发布时间】:2018-06-02 02:56:32
【问题描述】:

我刚刚开始学习 React,我想做的是设置一个简单的组件来调用特定的 API,并传递一个参数。

Axios:https://github.com/axios/axios 接口:https://dog.ceo/dog-api/

我的代码

import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';

class Itemlist extends React.Component {
    constructor() {
        super();
        this.state = {items: [], breedName: ''}
        this.fetchSubBreeds = this.fetchSubBreeds.bind(this);
        this.updateInputValue = this.updateInputValue.bind(this);
    }

    fetchSubBreeds() {
        axios.get('https://dog.ceo/api/breed/' + this.state.breedName + '/list')
        .then((response) => {
            this.setState({items: response.data.message})
        })
        .catch((error) => {
            this.setState({items: []});
            console.log(error);
        });
    }

    updateInputValue(evt) {
        this.setState({breedName: evt.target.value});
    }

    render() {
        return(
            <div>
                <label for='breed'>Breed name: </label>
                <input type='text' name='breed' 
                    onBlur={() => this.fetchSubBreeds()} 
                    onChange={(evt) => this.updateInputValue(evt)}>
                </input>
                <ul>
                    {this.state.items.map(item => <li key={item.id}>{item}</li>)}
                </ul>  
            </div>
        );
    }
}

export default Itemlist

当一个品种存在时,我得到了正确的子品种列表,但是当参数错误时,catch 函数似乎处于休眠状态,因为我收到了这个错误:

TypeError: this.state.items.map is not a function
render

  34 |             onChange={(evt) => this.updateInputValue(evt)}>
  35 |         </input>
  36 |         <ul>
> 37 |             {this.state.items.map(item => <li key={item.id}>{item}  </li>)}
  38 |         </ul>  
  39 |     </div>
  40 | );

API 错误响应:https://dog.ceo/api/breed/random/list

处理响应错误的正确方法是什么?

【问题讨论】:

  • 试试.then(response, error) 而不是.then(response).catch(error)
  • @Aaron 那不一样吗?
  • 它不一样,但在这种情况下它不会有任何区别...... Govind 想通了。 :)

标签: json reactjs promise axios


【解决方案1】:

问题在于,无论您是否提供有效品种,API 仍会以 200 状态代码(这意味着在 HTTP 领域中的成功)进行响应。由于 API 服务器以成功代码响应,因此永远不会调用 catch 语句。因此,您需要检查then 语句而不是catch。解析响应并检查状态属性是否等于“错误”。

fetchSubBreeds() {
    axios.get('https://dog.ceo/api/breed/' + this.state.breedName + '/list')
    .then((response) => {
        if(response.data.status==="error"){
           return console.log("breed doesn't exists"); //or whatever logic
        } else {
            this.setState({items: response.data.message})
        }

    })
    .catch((error) => {
        this.setState({items: []});
        console.log(error);
    });
}

【讨论】:

  • 谢谢。那么 .catch() 仅在 404 响应代码上触发?
  • 抛出错误时触发 Catch 语句。这取决于您或您正在使用的库的开发人员选择如何处理错误。在 Axios 的情况下,只要响应代码是失败代码,即 >=400,它就会触发 catch 语句。
猜你喜欢
  • 2017-07-07
  • 2020-12-14
  • 2018-04-26
  • 2021-09-30
  • 2020-06-30
  • 2019-05-27
  • 1970-01-01
  • 2016-07-08
  • 1970-01-01
相关资源
最近更新 更多