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

React Native使用Fetch获取API数据仅展示brand字段报错求助

解决React中渲染API返回数据时的"Objects are not valid as a React child"错误

嘿,我来帮你搞定这个报错问题!先理清楚你的情况:你想通过Fetch获取API数据并只展示brand字段,但遇到了对象不能作为React子元素的错误,这其实是因为你没正确处理API返回的数据结构。

首先明确你的API返回结构:

Object {
"data": Object {
"all": Array [
Object { "brand": "A1" },
Object { "brand": "B1" },
Object { "brand": "C1" }
]
}
}

错误原因分析

你现在直接在<Text>里写{data.data},但data.data是一个包含all数组的对象,React根本没办法直接把对象当成页面元素渲染,这就是你看到那个报错的核心原因。另外你的初始data状态设成了数组,但API返回的是对象,类型不匹配也会埋下隐患。

一步步修正方案

1. 调整状态定义和数据存储逻辑

把初始状态改成更贴合API返回的类型,而且直接提取我们需要的all数组存起来,这样后续渲染更方便:

// 把状态名改成brands,语义更清晰,初始值设为空数组
const [brands, setBrands] = useState([]);

// 在fetch的then回调里,直接提取API返回的all数组
.then((responseData)=> setBrands(responseData.data.all))

2. 修正渲染逻辑

现在brands是一个数组了,我们需要用map遍历它,把每个元素的brand字段单独渲染出来。同时别忘了处理加载状态,避免数据还没加载完成时出现错误。

完整修正后的代码

import { useState, useEffect } from 'react';
import { ScrollView, View, Text, StyleSheet } from 'react-native';

export default App = () => { 
  const [isLoading, setLoading] = useState(true); 
  const [brands, setBrands] = useState([]); 

  useEffect(() => { 
    fetch('https://你的API地址', { 
      method: 'POST', 
      timeout: 10000, 
      headers: { 
        Accept: 'application/json', 
        'Content-Type': 'application/json' 
      }, 
      // 提示:POST请求通常需要传递请求体,如果你的API要求的话,记得加上body参数,比如:
      // body: JSON.stringify({你的请求参数})
    }) 
    .then((response) => {
      // 新增:处理HTTP错误状态码(比如404、500)
      if (!response.ok) {
        throw new Error(`请求失败,状态码:${response.status}`);
      }
      return response.json();
    })
    .then((responseData) => { 
      console.log('API返回数据:', responseData);
      setBrands(responseData.data.all); 
    }) 
    .catch((error) => console.error('请求出错:', error)) 
    .finally(() => setLoading(false)); 
  }, []); // 依赖数组留空,确保组件只挂载时请求一次

  // 加载状态下显示提示
  if (isLoading) {
    return <Text style={styles.loadingText}>加载中...</Text>;
  }

  return ( 
    <ScrollView> 
      <View style={styles.container}> 
        {/* 遍历brands数组,渲染每个brand字段 */}
        {brands.map((item, index) => (
          <Text key={index} style={styles.brandItem}>
            {item.brand}
          </Text>
        ))}
      </View> 
    </ScrollView> 
  );
};

// 简单加些样式让页面更美观
const styles = StyleSheet.create({
  loadingText: {
    fontSize: 18,
    textAlign: 'center',
    marginTop: 20,
  },
  container: {
    padding: 16,
  },
  brandItem: {
    fontSize: 16,
    padding: 8,
    borderBottomWidth: 1,
    borderBottomColor: '#eee',
  },
});

几个关键的优化点

  • 把状态名改成brands,比原来的data更语义化,一眼就知道存的是品牌列表
  • 移除了原代码中useEffect依赖数组里的fetch和data,这两个是错误的依赖,会导致组件无限重复请求API
  • 新增了HTTP错误处理,能更清晰地排查请求失败的原因
  • 用map遍历数组渲染每个brand,给每个子元素加上key(实际项目中如果有唯一ID,建议用ID代替index)
  • 增加了加载状态的UI,提升用户体验

内容的提问来源于stack exchange,提问作者LuvYHWH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 19:07:47