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
相关产品推荐
相关产品推荐

