React Native中如何处理WebService返回的数组数据并实现显示?
我帮你梳理下代码里的几个关键问题,这些就是导致数据无法显示的核心原因,然后给你修正后的完整代码:
问题分析
- 网络请求位置错误:你把
fetch写在了组件类外部,既没法正确更新组件状态,还会导致this指向混乱,调用组件方法时出错。应该把请求放在组件生命周期方法里,比如componentDidMount,等组件挂载后再发起请求。 - 状态变量不匹配:state里定义的是
items数组存数据,但FlatList的data属性用的是this.state.dataSource,两者完全不对应,FlatList根本拿不到要渲染的数据。 - XML解析后未更新状态:你成功解析XML拿到
result后,没有把数据存入组件state,UI完全感知不到数据变化,自然没法显示。 - 方法定义位置错误:
fetchdata被写在了render函数内部,这不符合React组件的写法规范,应该把它放在组件类的方法层级(和render同级)。 - 加载状态逻辑混乱:原本的加载指示器逻辑写得不对,应该在
render里直接根据loading状态判断显示加载组件还是FlatList。
修正后的完整代码
import React from "react"; import { StyleSheet, View, ActivityIndicator, FlatList, Text, TouchableOpacity } from "react-native"; // 把依赖导入放在顶部,代码结构更清晰 const parseString = require('react-native-xml2js').parseString; export default class Source extends React.Component { static navigationOptions = ({ navigation }) => { return { title: "Source Listing", headerStyle: { backgroundColor: "#fff" }, headerTitleStyle: { textAlign: "center", flex: 1 } }; }; constructor(props) { super(props); this.state = { loading: true, // 初始设为true,页面先显示加载状态 items: [] // 统一用items存储接口返回的数据 }; } // 列表分隔线组件 FlatListItemSeparator = () => { return ( <View style={{ height: 0.5, width: "100%", backgroundColor: "rgba(0,0,0,0.5)" }} /> ); } // 封装网络请求方法 fetchData = async () => { try { const response = await fetch('http://192.168.200.133/apptak_service/apptak.asmx/Get_Item_Master'); const xmlText = await response.text(); parseString(xmlText, (err, result) => { if (err) { console.error('XML解析失败:', err); this.setState({ loading: false }); return; } // 重点!这里要根据你实际解析后的XML结构调整路径 // 比如假设解析后数组在result.Get_Item_MasterResponse.Get_Item_MasterResult里 // 你需要打印result看真实结构,替换下面的路径 const dataArray = result.YourRootNode.YourItemArray; this.setState({ items: dataArray, loading: false }); console.log('解析完成的数据:', dataArray); }); } catch (err) { console.log('网络请求失败:', err); this.setState({ loading: false }); } } // 组件挂载后发起请求 componentDidMount() { this.fetchData(); } renderItem = (data) => ( <TouchableOpacity style={styles.list}> <Text style={styles.lightText}>{data.item.name}</Text> <Text style={styles.lightText}>{data.item.email}</Text> {/* 用可选链避免company不存在时报错 */} <Text style={styles.lightText}>{data.item.company?.name}</Text> </TouchableOpacity> ) render() { // 根据loading状态切换显示内容 if (this.state.loading) { return ( <View style={styles.loader}> <ActivityIndicator size="large" color="#0c9" /> </View> ) } return ( <View style={styles.container}> <FlatList data={this.state.items} // 对应state里的items数组 ItemSeparatorComponent={this.FlatListItemSeparator} renderItem={this.renderItem} keyExtractor={(item) => item.id.toString()} /> </View> ) } } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#fff" }, loader: { flex: 1, justifyContent: "center", alignItems: "center", backgroundColor: "#fff" }, list: { paddingVertical: 4, margin: 5, backgroundColor: "#fff" }, lightText: { fontSize: 14, color: "#333", marginVertical: 2 } // 补上文字样式,避免看不见内容 });
额外提醒
- 一定要打印
result查看XML解析后的真实结构,调整dataArray的取值路径,这是确保数据能正确存入state的关键。 - 我给
lightText补上了基础样式,避免因为没有字体颜色/大小导致文字看不见的情况。 - 用
async/await重构了请求代码,比链式then更易读,你也可以根据习惯改回链式写法。
内容的提问来源于stack exchange,提问作者Rishail Siddiqui
相关产品推荐
相关产品推荐

