如何用React Hooks实现餐厅菜单API数据的类别筛选功能?
餐厅菜单按类别筛选功能实现方案
问题描述
已基于React的useState、useEffect Hooks完成餐厅菜单页面的API数据获取与类别tab切换基础功能,但尚未实现按类别名称筛选数据的需求,需要修改代码实现仅展示指定类别数据的功能。当前代码如下:
import React, { useState, useEffect } from 'react'; const Menu = () => { /*Toggle sidemenu start*/ const [toggleState, setToggleState] = useState(1); const toggleTab = (index) =>{ setToggleState(index); } /*Toggle sidemenu end*/ /* API Data start */ const [data, setData] = useState(); useEffect(() => { async function fetchData() { try { const response = await fetch('https://63b040676a74151a1bbcf341.mockapi.io/restaurantmenu') const data = await response.json(); setData(data); console.log("data") } catch (error) { console.error(error); } } fetchData(); }, []); /* API Data end */ return ( <div className='main-content'> <div className='restaurant-card'> <div className='image'> <img src='/images/kfc.png'/> </div> <div className='restaurant-details'> <h2>KFC</h2> <p>Abids, Hyderabad</p> <p><img src='/images/rating.png'/><span>4.5 Rating | 09:00 A.M - 11:00 P.M</span></p> </div> </div> <div className='item-category'> <h3>Categories</h3> <ul> <li className={toggleState === 1 ? "tabs active" : "tabs"} onClick={()=>toggleTab(1)}>Pizza</li> <li className={toggleState === 2 ? "tabs active" : "tabs"} onClick={()=>toggleTab(2)}>Bread</li> <li className={toggleState === 3 ? "tabs active" : "tabs"} onClick={()=>toggleTab(3)}>Shakes</li> <li className={toggleState === 4 ? "tabs active" : "tabs"} onClick={()=>toggleTab(4)}>Ice Cream</li> <li className={toggleState === 5 ? "tabs active" : "tabs"} onClick={()=>toggleTab(5)}>Cakes</li> <li className={toggleState === 6 ? "tabs active" : "tabs"} onClick={()=>toggleTab(6)}>Juices</li> </ul> </div> <div className='item-list'> <div className="box"> <input type="text" className="search-input" placeholder="Search for dishes"/> <img src='/images/search.png'/> </div> <div className="content"> { data ? ( <div> <div> {data.map(item => <div> <h2>{item.Category}</h2> <div className='items' key={item.id}> <ul> <li>{item.Type}</li> <li>{item.Name}</li> <li>₹ {item.Price}</li> <div className='hr'></div> </ul> </div> </div> )} </div> </div> ) : (<div>Loading...</div>) } </div> </div> </div> ) } export default Menu;
实现方案
核心思路
将当前基于数字索引的tab切换,改为直接绑定类别名称,通过filter方法筛选出对应类别的数据后再渲染。
具体修改步骤
替换激活状态存储方式
把原来存储数字索引的toggleState,改为存储类别名称的activeCategory,初始值设为默认选中的类别(比如"Pizza"):const [activeCategory, setActiveCategory] = useState("Pizza");修改tab切换函数
让toggleTab直接接收类别名称作为参数,更新激活状态:const toggleTab = (category) => { setActiveCategory(category); };更新tab项的选中判断逻辑
将每个tab的className判断条件改为对比类别名称:<li className={activeCategory === "Pizza" ? "tabs active" : "tabs"} onClick={()=>toggleTab("Pizza")}>Pizza</li> <!-- 其他类别项同理修改 -->添加数据筛选逻辑
在组件内计算筛选后的数据,匹配当前激活的类别:const filteredData = data?.filter(item => item.Category === activeCategory) || [];修改渲染逻辑
用筛选后的filteredData替代原data进行渲染,同时优化类别标题的展示(避免重复渲染同一类别标题):{data ? ( filteredData.length > 0 ? ( <div> <h2>{activeCategory}</h2> {filteredData.map(item => ( <div className='items' key={item.id}> <ul> <li>{item.Type}</li> <li>{item.Name}</li> <li>₹ {item.Price}</li> <div className='hr'></div> </ul> </div> ))} </div> ) : ( <div>No items found in this category</div> ) ) : ( <div>Loading...</div> )}
完整修改后的代码
import React, { useState, useEffect } from 'react'; const Menu = () => { // 直接存储当前激活的类别名称 const [activeCategory, setActiveCategory] = useState("Pizza"); const toggleTab = (category) => { setActiveCategory(category); }; const [data, setData] = useState(); useEffect(() => { async function fetchData() { try { const response = await fetch('https://63b040676a74151a1bbcf341.mockapi.io/restaurantmenu') const data = await response.json(); setData(data); } catch (error) { console.error(error); } } fetchData(); }, []); // 筛选当前激活类别的数据 const filteredData = data?.filter(item => item.Category === activeCategory) || []; return ( <div className='main-content'> <div className='restaurant-card'> <div className='image'> <img src='/images/kfc.png'/> </div> <div className='restaurant-details'> <h2>KFC</h2> <p>Abids, Hyderabad</p> <p><img src='/images/rating.png'/><span>4.5 Rating | 09:00 A.M - 11:00 P.M</span></p> </div> </div> <div className='item-category'> <h3>Categories</h3> <ul> <li className={activeCategory === "Pizza" ? "tabs active" : "tabs"} onClick={()=>toggleTab("Pizza")}>Pizza</li> <li className={activeCategory === "Bread" ? "tabs active" : "tabs"} onClick={()=>toggleTab("Bread")}>Bread</li> <li className={activeCategory === "Shakes" ? "tabs active" : "tabs"} onClick={()=>toggleTab("Shakes")}>Shakes</li> <li className={activeCategory === "Ice Cream" ? "tabs active" : "tabs"} onClick={()=>toggleTab("Ice Cream")}>Ice Cream</li> <li className={activeCategory === "Cakes" ? "tabs active" : "tabs"} onClick={()=>toggleTab("Cakes")}>Cakes</li> <li className={activeCategory === "Juices" ? "tabs active" : "tabs"} onClick={()=>toggleTab("Juices")}>Juices</li> </ul> </div> <div className='item-list'> <div className="box"> <input type="text" className="search-input" placeholder="Search for dishes"/> <img src='/images/search.png'/> </div> <div className="content"> {data ? ( filteredData.length > 0 ? ( <div> <h2>{activeCategory}</h2> {filteredData.map(item => ( <div className='items' key={item.id}> <ul> <li>{item.Type}</li> <li>{item.Name}</li> <li>₹ {item.Price}</li> <div className='hr'></div> </ul> </div> ))} </div> ) : ( <div>No items found in this category</div> ) ) : ( <div>Loading...</div> )} </div> </div> </div> ) } export default Menu;
内容的提问来源于stack exchange,提问作者sai charan
相关产品推荐
相关产品推荐

