React中如何从Props提取API返回的JSON数据并展示菜单
解决React中API返回套餐数据展示到Tabs标签页的问题
我来帮你一步步搞定这个需求!咱们从数据处理、标签页渲染到内容切换,把每个环节都理清楚。
1. 先对齐API数据结构(假设你的返回格式类似这样)
先模拟一个符合需求的API返回JSON,方便后续代码示例参考:
{ "mealPackages": [ { "packageId": "breakfast", "packageName": "元气早餐套餐", "packageMenu": [ { "dishId": "b1", "name": "现磨豆浆", "price": 4 }, { "dishId": "b2", "name": "鲜肉包子", "price": 6 } ] }, { "packageId": "lunch", "packageName": "工作日午餐套餐", "packageMenu": [ { "dishId": "l1", "name": "番茄炒蛋", "price": 18 }, { "dishId": "l2", "name": "杂粮米饭", "price": 3 } ] } ] }
2. 完整React组件实现(含注释)
下面是可直接复用的组件示例,包含API请求、Tabs渲染和内容切换逻辑:
import { useState, useEffect } from 'react'; const PackageMenuTabs = () => { // 存储API返回的套餐数据 const [packageList, setPackageList] = useState([]); // 记录当前选中的标签索引 const [activeTab, setActiveTab] = useState(0); // 1. 组件挂载时请求API数据 useEffect(() => { const fetchMealPackages = async () => { try { const res = await fetch('你的API接口地址'); const data = await res.json(); // 根据你实际的API结构调整,这里假设套餐数组在data.mealPackages里 setPackageList(data.mealPackages); } catch (err) { console.error('获取套餐数据失败:', err); } }; fetchMealPackages(); }, []); // 2. 处理标签切换事件 const handleTabClick = (index) => { setActiveTab(index); }; // 数据未加载完成时显示加载状态 if (packageList.length === 0) { return <div style={{ padding: '20px' }}>加载中...</div>; } return ( <div style={{ maxWidth: '800px', margin: '20px auto' }}> {/* 标签页头部 */} <div style={{ display: 'flex', borderBottom: '1px solid #eee' }}> {packageList.map((pkg, index) => ( <button key={pkg.packageId} style={{ padding: '10px 20px', border: 'none', background: activeTab === index ? '#f5f5f5' : 'transparent', cursor: 'pointer', fontSize: '16px', fontWeight: activeTab === index ? 'bold' : 'normal', borderBottom: activeTab === index ? '2px solid #1890ff' : 'none' }} onClick={() => handleTabClick(index)} > {pkg.packageName} </button> ))} </div> {/* 当前标签对应的餐品内容 */} <div style={{ padding: '20px' }}> <h3>{packageList[activeTab].packageName} 餐品列表</h3> <ul style={{ listStyle: 'none', paddingLeft: 0 }}> {packageList[activeTab].packageMenu.map(dish => ( <li key={dish.dishId} style={{ padding: '8px 0', borderBottom: '1px dashed #eee' }}> <span>*{dish.name}*</span> <span style={{ float: 'right', color: '#f5222d' }}>¥{dish.price}</span> </li> ))} </ul> </div> </div> ); }; export default PackageMenuTabs;
3. 关键逻辑拆解
- 数据获取:用
useEffect在组件首次挂载时发起API请求,把返回的套餐数组存入状态packageList,注意要根据你实际的API返回结构调整赋值逻辑。 - 标签生成:通过
map遍历packageList,为每个套餐生成一个标签按钮,用套餐的packageId作为唯一key,避免React渲染警告。 - 内容切换:用
activeTab状态记录当前选中的标签索引,点击标签时更新索引,然后根据索引从packageList中取出对应套餐的packageMenu数组,遍历渲染餐品。 - 状态提示:在数据未加载完成时显示"加载中...",避免页面出现空白或错误。
4. 适配不同UI库的小技巧
如果你用Ant Design、Material UI这类组件库,只需要把自定义的标签按钮替换成对应库的Tabs和Tab组件即可,核心逻辑完全一致:
比如Ant Design的写法:
import { Tabs } from 'antd'; const { TabPane } = Tabs; // ... 其他逻辑不变 return ( <Tabs activeKey={String(activeTab)} onChange={(key) => setActiveTab(Number(key))}> {packageList.map((pkg, index) => ( <TabPane tab={pkg.packageName} key={String(index)}> {/* 餐品列表内容 */} </TabPane> ))} </Tabs> );
内容的提问来源于stack exchange,提问作者Tammy
相关产品推荐
相关产品推荐

