You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中如何处理WebService返回的数组数据并实现显示?

我帮你梳理下代码里的几个关键问题,这些就是导致数据无法显示的核心原因,然后给你修正后的完整代码:

问题分析

  1. 网络请求位置错误:你把fetch写在了组件类外部,既没法正确更新组件状态,还会导致this指向混乱,调用组件方法时出错。应该把请求放在组件生命周期方法里,比如componentDidMount,等组件挂载后再发起请求。
  2. 状态变量不匹配:state里定义的是items数组存数据,但FlatList的data属性用的是this.state.dataSource,两者完全不对应,FlatList根本拿不到要渲染的数据。
  3. XML解析后未更新状态:你成功解析XML拿到result后,没有把数据存入组件state,UI完全感知不到数据变化,自然没法显示。
  4. 方法定义位置错误:fetchdata被写在了render函数内部,这不符合React组件的写法规范,应该把它放在组件类的方法层级(和render同级)。
  5. 加载状态逻辑混乱:原本的加载指示器逻辑写得不对,应该在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 09:47:40