在反应中未能抓住承诺

Fail catching a promises in react

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

Axios:https://github.com/axios/axios API: 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

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

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

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);
    });
}