我正在尝试从API提取数据,但是我只能提取最高级别的数据。当我尝试访问嵌套在类别下的内容时,出现错误:undefined is not an object (evaluating 'this.state.data.order.name' )
。
从我读到的内容来看,状态可能是一个问题,但是我是本机反应的新手,我不确定该如何解决。
这是API结构
render(){
const { data } = this.state;
return(
<ScrollView style={styles.containerxd}>
<TouchableOpacity style={styles.textStyle}>
<Image
source={require('./images/burger.png')}
style={styles.ImageIconStyle} />
</TouchableOpacity>
<View style={styles.white}>
<View style={{flex:1, alignItems:'center', justifyContent:'center'}}>
<View style={styles.tabHeader}><Text style={styles.textHeader}>Scientific name</Text></View>
<View style={styles.tabContent}><Text style={styles.textContent}>{this.state.data.scientific_name}</Text></View>
<View style={styles.tabHeader}><Text style={styles.textHeader}>Common name</Text></View>
<View style={styles.tabContent}><Text style={styles.textContent}>{this.state.data.common_name}</Text></View>
<View style={styles.tabHeader}><Text style={styles.textHeader}>Moisture use</Text></View>
<View style={styles.tabContent}><Text style={styles.textContent}>{this.state.data.order.name}</Text></View>
科学名称和通用名称显示得很好,但是每降低一个数据级别都会出现错误。
答案 0 :(得分:1)
您需要验证数据。未定义订单时,执行order.name
将破坏您的应用。改变
<View style={styles.tabContent}><Text style={styles.textContent}>{this.state.data.order.name}</Text></View>
到
const { data } = this.state;
const name = data && data.order && data.order.name || '';
// rest of the code here
<View style={styles.tabContent}><Text style={styles.textContent}>{name}</Text></View>
注意
始终验证您的数据。不要以为您将始终获得正确的数据。如果data.name
为null或未定义,则在使用对象时总是要像对data
那样进行验证,这可能会破坏您的应用程序。例如,给定以下对象。
const animal = {};
做
// throws an error, Cannot read property 'toLowerCase' of undefined
console.log(animal.name.toLowerCase())
为防止这种情况发生,我们需要检查属性是否存在,如下所示。
// checks if the name property exists console name, else assign a console log 'Lion'
console.log(animal.name && animal.name.toLowerCase() || 'Lion')
第二个选项
添加一个加载器,从api提取数据时显示Loading...
文本,一旦请求完成,将加载器设置为false并显示您的数据。
fetchData = async () => {
const res = await fetch(...)
...
this.setState({ isLoading: false, data: response.data });
}
render() {
return (
<ScrollView style={styles.containerxd}>
<TouchableOpacity style={styles.textStyle}>
<Image
source={require('./images/burger.png')}
style={styles.ImageIconStyle}
/>
</TouchableOpacity>
{this.state.isLoading ? (
<Text>Loading...</Text>
) : (
<View style={styles.white}>
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}}
>
<View style={styles.tabHeader}>
<Text style={styles.textHeader}>Scientific name</Text>
</View>
<View style={styles.tabContent}>
<Text style={styles.textContent}>
{this.state.data.scientific_name}
</Text>
</View>
<View style={styles.tabHeader}>
<Text style={styles.textHeader}>Common name</Text>
</View>
<View style={styles.tabContent}>
<Text style={styles.textContent}>
{this.state.data.common_name}
</Text>
</View>
<View style={styles.tabHeader}>
<Text style={styles.textHeader}>Moisture use</Text>
</View>
<View style={styles.tabContent}>
<Text style={styles.textContent}>
{this.state.data.order.name}
</Text>
</View>
</View>
</View>
)}
</ScrollView>
);
}