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

React Native调用SQL Server后端API渲染列表报错排查

React Native 列表渲染报错修复方案

你遇到的 Text strings must be rendered within a <Text> component 报错和列表不渲染问题,由多个代码逻辑错误共同导致,接口返回数据参考如下:
接口返回数据截图

核心错误点

  • 函数组件和类组件写法混用:你使用了useState/useEffect的函数组件写法,但代码里大量使用只有类组件才存在的this.setState、this.props、this.xxx调用,函数组件没有this实例,这些逻辑全部无效,状态根本无法正常更新。
  • 列表组件API使用错误:旧版ListView早已被官方废弃移除,替换为FlatList后你仍然套用ListView的DataSource/cloneWithRows逻辑,而FlatList不需要额外包装数据源,直接接收原始数组即可。
  • 渲染参数传递错误:FlatList的renderItem回调参数为包裹对象,真实行数据存在item字段下,你直接读取参数对象的job字段会拿到undefined;ItemSeparatorComponent需要传入组件引用,你直接执行组件函数传入返回值,会触发渲染异常。
  • 请求配置错误:React Native环境没有浏览器的跨域限制,不需要加no-cors参数;真机调试时localhost指向的是手机本身,无法访问你电脑上的本地服务。
  • 未校验接口返回格式:如果你的PHP接口返回的是带状态码的包裹结构(比如{code:200, data: 数组}),直接把整个响应当列表数组传入,FlatList遍历时会拿到非预期值,触发文本渲染报错。

修复后可直接运行的代码

import React, { useState, useEffect } from 'react';
import {View, Text, StyleSheet, ActivityIndicator, Platform, FlatList} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import {StatusBar} from 'expo-status-bar';

export default function StopJob(){
  const [isLoading, setIsLoading] = useState(true);
  // 直接存储接口返回的原始数组,不需要额外DataSource包装
  const [listData, setListData] = useState([]);
  // 函数组件通过钩子获取navigation实例,不需要走this.props
  const navigation = useNavigation();

  useEffect(()=>{
    // 注意:真机调试替换为你电脑的局域网IP,安卓模拟器可使用10.0.2.2访问电脑本地服务
    fetch('http://你的服务地址/api/findid.php')
      .then((response) => response.json())
      .then((responseJson) => {
        setIsLoading(false);
        // 按接口实际结构调整取值,如果接口返回包裹结构就取对应数组字段,这里做了数组类型兜底
        setListData(Array.isArray(responseJson) ? responseJson : []);
      })
      .catch((error) => {
        console.error('接口请求异常:', error);
        setIsLoading(false);
      })
  },[]);

  // 行点击跳转逻辑
  const handleRowPress = (rowData) => {
    navigation.navigate('Third', { 
      Userid : rowData.user,
      Job : rowData.job,
      JobId : rowData.jobid,
      MachineCode : rowData.machinecode,
      StartTime : rowData.startTime
    });
  }

  // 列表分隔线组件
  const ItemSeparator = () => {
    return (
      <View
        style={{
          height: .5,
          width: "100%",
          backgroundColor: "#000",
        }}
      />
    );
  }

  // 加载态渲染
  if(isLoading){
    return(
      <View style={{flex: 1, paddingTop: 20}}>
        <ActivityIndicator /> 
      </View>
    )
  }

  return(
    <View style={styles.mainContainer}>
      <FlatList
        data={listData}
        // 保证key唯一,如果jobid为唯一值可替换为item => String(item.jobid)
        keyExtractor={(item, index) => String(item.user || index)}
        ItemSeparatorComponent={ItemSeparator}
        renderItem={ ({item}) => (
          <Text 
            style={styles.rowText} 
            onPress={() => handleRowPress(item)}
          > 
            {item.job} 
          </Text>
        )}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  mainContainer :{
    flex:1,
    paddingTop: Platform.OS === 'ios' ? 20 : 0,
    marginLeft: 5,
    marginRight: 5
  },
  rowText: {
    fontSize: 20,
    paddingRight: 10,
    paddingTop: 10,
    paddingBottom: 10,
  }
});

调试注意事项

  • 代码跑通前先在fetch的then回调里打印responseJson,确认接口返回的是纯数组还是带外层包裹的结构,如果是包裹结构要取到实际的列表数组再存入state。
  • 本地调试时确保手机和电脑连接同一个WiFi,关闭电脑的公共网络防火墙,否则手机无法访问你电脑上启动的本地服务。
  • 不要参考发布时间过早的React Native教程,2020年之后的RN版本已经彻底移除ListView,类组件的示例代码直接套用到函数组件中必然出现兼容性问题。

内容的提问来源于stack exchange,提问作者d.chan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:45:29