React Native DataTable获取数据报错data.articles.map未定义
问题现象
在React Native项目中使用DataTable组件拉取并渲染接口数据时,触发报错:
undefined is not an object (evaluating 'data.articles.map')
完整错误信息:Cannot read properties of undefined ('map')
原有业务代码
import React, { useState,useEffect } from 'react'; import { StyleSheet, SafeAreaView, ScrollView,Text, View, Modal } from 'react-native'; import { DataTable } from 'react-native-paper'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import COLORS from '../src/conts/colors'; import Button from '../src/views/components/Button'; const List = ({navigation}) => { const [data,setData] = useState([]) const [loading,setLoading]= useState(true) const fetchData = ()=>{ fetch("https://flow.simpas.ai/hortus/paysagiste/category?businessid=0899607494") .then(res=>res.json()) .then(results=>{ setData(results) setLoading(false) }) } useEffect(()=>{ fetchData() },[]) const RenderCollection = ({item}) =>{ return( <DataTable.Row style={styles.tableRow} key={item.businessid}> <DataTable.Cell textStyle={{color: '#777777',fontFamily: 'Roboto'}} onPress={() => navigation.navigate("Edit",{item})} >{item.title}</DataTable.Cell> <DataTable.Cell textStyle={{color: '#FEB296', fontFamily: 'Roboto'}}>{item.title}</DataTable.Cell> <DataTable.Cell textStyle={{color: '#777777', fontFamily: 'Roboto'}}>{item.price}</DataTable.Cell> </DataTable.Row> ) } return ( <SafeAreaView style={{ flex: 1}}> <ScrollView contentContainerStyle={{paddingTop: 50, paddingHorizontal: 20}}> <Text style={{color: COLORS.black, fontSize: 40, fontWeight: 'bold', fontFamily: 'Roboto',textAlign: 'center'}}> List of Companies </Text> <Text style={{color: COLORS.grey, fontSize: 18, marginVertical: 10, fontFamily: 'Roboto', textAlign: 'center'}}> Check Our Companies Details </Text> <DataTable style={styles.container} > <DataTable.Header style={styles.tableHeader} > <DataTable.Title textStyle={{color: '#fff',fontSize: 16, fontFamily: 'Roboto'}}>BusinessId</DataTable.Title> <DataTable.Title textStyle={{color: '#fff',fontSize: 16, fontFamily: 'Roboto'}}>Title</DataTable.Title> <DataTable.Title textStyle={{color: '#fff',fontSize: 16, fontFamily: 'Roboto'}}>Price</DataTable.Title> </DataTable.Header> </DataTable> { data && data.articles.map(article => <RenderCollection item={article} />) } </ScrollView> </SafeAreaView> ); }; export default List;
问题原因
- 初始渲染阶段报错:
data的初始值是空数组,空数组不存在articles属性,此时访问data.articles得到undefined,对undefined调用map方法直接触发错误。原有代码仅判断了data是否存在,没有校验data.articles的合法性,判断逻辑无效。 - 接口逻辑有缺陷:fetch请求没有添加错误捕获,也没有校验接口返回的HTTP状态,一旦请求失败、接口返回结构和预期不符(比如列表字段不是
articles、返回层级不对),不仅会触发报错,还会导致loading状态一直卡在true。 - 组件写法问题:
DataTable.Row被写在了DataTable组件外部,不符合react-native-paper的组件嵌套要求,会出现样式错乱问题。
修复方案
- 补全数据校验逻辑,使用可选链+数组类型判断+兜底空数组,避免访问不存在的属性时报错;配合loading状态在数据加载完成前展示提示文案。
- 给fetch请求增加错误捕获和HTTP状态校验,请求过程中正确维护loading状态,同时打印接口返回结果,确认实际的列表字段名,不要硬写
articles字段。 - 调整组件嵌套结构,把渲染的
DataTable.Row放到DataTable组件内部。
关键修改代码
修复后的fetch请求逻辑
const fetchData = ()=>{ setLoading(true) fetch("https://flow.simpas.ai/hortus/paysagiste/category?businessid=0899607494") .then(res=>{ if(!res.ok) throw new Error('接口请求异常') return res.json() }) .then(results=>{ console.log('接口返回完整结果:', results) // 打印确认列表字段名,不要硬写articles setData(results) setLoading(false) }) .catch(err=>{ console.error('请求失败:', err) setLoading(false) }) }
修复后的列表渲染逻辑
<DataTable style={styles.container}> <DataTable.Header style={styles.tableHeader}> <DataTable.Title textStyle={{color: '#fff',fontSize: 16, fontFamily: 'Roboto'}}>BusinessId</DataTable.Title> <DataTable.Title textStyle={{color: '#fff',fontSize: 16, fontFamily: 'Roboto'}}>Title</DataTable.Title> <DataTable.Title textStyle={{color: '#fff',fontSize: 16, fontFamily: 'Roboto'}}>Price</DataTable.Title> </DataTable.Header> { loading ? <DataTable.Row><DataTable.Cell>数据加载中...</DataTable.Cell></DataTable.Row> : Array.isArray(data?.articles) ? data.articles.map(article => <RenderCollection item={article} key={article.businessid} />) : <DataTable.Row><DataTable.Cell>暂无数据</DataTable.Cell></DataTable.Row> } </DataTable>
注意:如果控制台打印的接口返回结果里没有
articles字段,把代码里的articles替换成接口实际返回的列表数组字段名即可。
内容的提问来源于stack exchange,提问作者HASSANE BOUKHAL
相关产品推荐
相关产品推荐

