繁体   English   中英

反应。 如何仅使用现有密钥的fetch和setState处理API响应中的缺失密钥?

[英]React. How to deal with missing keys in API response using fetch and setState only for existing keys?

我正在使用公共API来获取一些数据的React项目上工作。 问题是我发现很多有趣且绝对有价值的API可能会丢失一些数据。 例如,我使用的是waqi.info,它从世界各地的车站收集有关空气质量的信息。 这是一个问题-当我发送请求时,我需要来自特定键的值以响应JSON。 有些工作站不收集部分数据,因此我没有在JSON中寻找密钥。 结果我得到了我所期望的:

Uncaught (in promise) TypeError: Cannot read property 'v' of undefined

我只需要在响应中存在键的情况下更改状态,或者更好-将状态设置为给定值,例如“无数据”。 我可以手动检查每个键是否为“ undefined”,但它非常粗糙,我正在寻找更智能,更优雅的产品。 组件代码(从大多数不必要的内容中删除)在这里:

class Item extends React.Component {
    constructor(){
        super();
        this.state={
            dataSourceName: null,
            dataSourceDetailsCO: null,
            dataSourceDetailsNO2: null,
            dataSourceDetailsPM10: null,
            dataSourceDetailsPM25: null,
            dataSourceDetailsSO2: null, 
            dataSourceDetailsTemp: null,
            dataSourceDetailsWind: null
        }; 
    }
    fetchStationDetails = () => {
        const stationUid = this.props.uid;
        const urlStationDetails = 'https://api.waqi.info/feed/@' + stationUid + '/?token=' + apiKey;
        fetch(urlStationDetails)
            .then(res => res.json())
            .then(json => this.setState({
                dataSourceName: json.data.attributions[0].name,
                dataSourceDetailsCO: json.data.iaqi.co.v,
                dataSourceDetailsNO2: json.data.iaqi.no2.v,
                dataSourceDetailsPM10: json.data.iaqi.pm10.v,
                dataSourceDetailsPM25: json.data.iaqi.pm25.v,
                dataSourceDetailsSO2: json.data.iaqi.so2.v, 
                dataSourceDetailsTemp: json.data.iaqi.t.v,
                dataSourceDetailsWind: json.data.iaqi.w.v
            })) 
    }
    render(){
        const dataSourceName = this.state.dataSourceName;
        return (
            <li>
                <div>
                    Id: {this.props.uid} Longitude: {this.props.lon} Latitude: {this.props.lat}
                </div>
                <div>
                    General Air Quality Index (AQI): {this.props.aqi}
                </div>
                <div>
                    <button onClick={this.fetchStationDetails}>Click to get detailed data</button>
                </div>
                {dataSourceName ? <ItemData 
                    dataSourceName={this.state.dataSourceName}
                    dataSourceDetailsCO={this.state.dataSourceDetailsCO}
                    dataSourceDetailsNO2={this.state.dataSourceDetailsNO2}
                    dataSourceDetailsPM10={this.state.dataSourceDetailsPM10}
                    dataSourceDetailsPM25={this.state.dataSourceDetailsPM25}
                    dataSourceDetailsSO2={this.state.dataSourceDetailsSO2}
                    dataSourceDetailsTemp={this.state.dataSourceDetailsTemp}
                    dataSourceDetailsWind={this.state.dataSourceDetailsWind}
                /> : null }
            </li>
        )
    }
}

先感谢您 :)

这是一个常见的问题,您始终需要考虑到这一点,您应该尝试做的是解析JSON并检查您要查找的节点是否已定义或创建了白名单,而且您的重复项很多您可以清理并使其更清晰的代码:

whiteList = {
    dataSourceName:"co",
    dataSourceDetailsNO2:"no2",
    dataSourceDetailsPM10:"pm10",
    ...
    ...
}

parseData = (data) => {
    try{
        Object.entries(this.whiteList).forEach(([key, value]) => {

            this.setState({
               [key]:data.data.iaqi[value].v
            })
        })
    }catch(e){
        //handle Errors
    }
}


fetchStationDetails = () => {
    const {uid} = this.props;

    const urlStationDetails = `https://api.waqi.info/feed/@${uid}/?token=${apiKey}`;

    fetch(urlStationDetails)
        .then(res => res.json())
        .then(json => this.parseData(json)) 
        .catch(console.log)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM