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

React组件传参求助:创建独立组件调用API传递指定格式数组

React新手求助:替换Mock数据为API获取的独立组件

我是React新手,现有DashboardContent组件通过mockData数组渲染StatsGroup组件,想要替换成一个可独立维护的组件,通过API调用获取数据并转换成mockData指定的格式后传给StatsGroup。

现有渲染组件代码

export function DashboardContent() {
    return (
        <Grid>
            <Grid.Col sm={12} md={12} lg={4}>
                <ProfileCard />
            </Grid.Col>
            <Grid.Col sm={12} md={12} lg={8}>
                <Flex direction="column" h="100%" justify="space-between" gap="md">
                    <WelcomeCard />
                    <StatsGroup data={mockData} />
                </Flex>
            </Grid.Col>
            <Grid.Col sm={12} md={12} lg={8}>
                <BalanceCard />
            </Grid.Col>
            <Grid.Col sm={12} md={12} lg={4}>
                <OverviewCard />
            </Grid.Col>
        </Grid>
    );
}

当前使用的模拟数据

export const mockData = [
    {
        title: 'ABC',
        value: '$7,999',
        diff: 50,
    },
    {
        title: 'XXX',
        value: '$4,00',
        diff: -13,
    },
    {
        title: 'Null',
        value: '$ 0.745',
        diff: 1,
    },
];

我尝试的代码(未成功)

import React, { useEffect, useState } from 'react';
import axios from 'axios';

interface CustomArray {
    title: string;
    value: string;
    diff: number;
}
const token =
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

const axiosInstance = axios.create({
    headers: {
        Authorization: `Bearer ${token}`,
    },
});
const Usage = () => {
    const [users, setUsers] = useState([]);

    const fetchUsers = async () => {
        const response = await axios.get(
            'https://myrestservices.com/api/v2/organizations/AXZ/usage'
        );
        const usersData = response.data;

        const usersArray = usersData.map(user => ({
            title: user.title,
            value: user.value,
            diff: user.diff,
        }));

        setUsers(usersArray);
    };

    useEffect(() => {
        fetchUsers();
    }, []);

    return users;
};

export default Usage;

问题分析与解决方案

你的代码存在几个关键问题:

  • React组件不能直接返回数组,必须返回合法JSX元素
  • 未使用创建好的axiosInstance,全局axios请求没带上授权头
  • 状态初始化未指定类型,类型不安全
  • 缺少错误处理,API请求失败会导致页面异常

以下是修正后的独立组件,同时增加了加载状态和错误处理:

import React, { useEffect, useState } from 'react';
import axios from 'axios';
// 引入StatsGroup组件,确保路径正确
import { StatsGroup } from './StatsGroup';

// 定义与mockData完全匹配的类型
interface StatItem {
    title: string;
    value: string;
    diff: number;
}

const token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

// 复用创建好的带授权头的axios实例
const axiosInstance = axios.create({
    headers: {
        Authorization: `Bearer ${token}`,
    },
});

// 独立的数据获取+渲染组件
const StatsDataProvider = () => {
    const [statsData, setStatsData] = useState<StatItem[]>([]);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<string | null>(null);

    const fetchStatsData = async () => {
        try {
            setLoading(true);
            // 使用axiosInstance发起请求,确保授权头生效
            const response = await axiosInstance.get(
                'https://myrestservices.com/api/v2/organizations/AXZ/usage'
            );
            // 将API返回数据转换为mockData格式
            const formattedData = response.data.map((item: any) => ({
                title: item.title || '', // 处理字段缺失的边界情况
                value: `$${item.value}` || '$0', // 统一添加$符号,匹配mock格式
                diff: typeof item.diff === 'number' ? item.diff : 0 // 确保diff为数字类型
            }));
            setStatsData(formattedData);
            setError(null);
        } catch (err) {
            setError('数据加载失败,请稍后重试');
            console.error('API请求错误:', err);
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        fetchStatsData();
    }, []);

    // 根据状态返回对应内容
    if (loading) {
        return <div>加载中...</div>; // 可替换为项目内统一的加载组件
    }

    if (error) {
        return <div className="text-red-500">{error}</div>; // 错误提示
    }

    // 返回StatsGroup并传入转换后的数据
    return <StatsGroup data={statsData} />;
};

export default StatsDataProvider;

修改DashboardContent组件,替换原StatsGroup引用:

import StatsDataProvider from './StatsDataProvider'; // 引入新组件

export function DashboardContent() {
    return (
        <Grid>
            <Grid.Col sm={12} md={12} lg={4}>
                <ProfileCard />
            </Grid.Col>
            <Grid.Col sm={12} md={12} lg={8}>
                <Flex direction="column" h="100%" justify="space-between" gap="md">
                    <WelcomeCard />
                    {/* 替换原StatsGroup为新的Provider组件 */}
                    <StatsDataProvider />
                </Flex>
            </Grid.Col>
            <Grid.Col sm={12} md={12} lg={8}>
                <BalanceCard />
            </Grid.Col>
            <Grid.Col sm={12} md={12} lg={4}>
                <OverviewCard />
            </Grid.Col>
        </Grid>
    );
}

额外提示

  • 若API返回字段名与mockData不一致,需在formattedData的map函数中做字段映射(比如API返回name对应mock的title,则写title: item.name)
  • 不要硬编码token,建议放在环境变量中(如process.env.REACT_APP_API_TOKEN)
  • 加载状态和错误提示可替换为项目内统一组件,保持风格一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 14:54:52