如何用Headless UI Tabs实现所有数组项在各标签页均展示
问题:让所有内容显示在每个Headless UI标签页中
我想把数组里的所有内容展示在每一个Headless UI标签页里,但目前只能按分类展示对应内容,没法实现每个标签页都显示全部内容的效果。预期效果如下:

当前实现代码:
export default function ServicetList() { const [tabs] = useState({ NAS: [ { id: 1, name: "DSM", href: "#", category: "NAS", }, ], Email: [ { id: 1, name: "Webmail", href: "#", category: "Email", }, }); return ( <div> <Tab.Group> <Tab.List> {Object.keys(tabs).map((category) => (<Tab key={category}>{category}</Tab>))} </Tab.List> <Tab.Panels> {Object.values(tabs).map((services, idx) => ( <Tab.Panel key={idx}> <ul role="list"> {services.map((service) => ( <li key={service.id}><h3>{service.name}</h3></li> ))} </ul> </Tab.Panel> ))} </Tab.Panels> </Tab.Group> </div> ); }
解决方案
你现在的问题是每个标签页只渲染了对应分类的内容,要实现每个标签页显示全部内容,只需要先把所有分类的服务合并成一个数组,然后在每个Tab.Panel里渲染这个合并后的数组就行。
修改后的代码:
export default function ServicetList() { const [tabs] = useState({ NAS: [ { id: 1, name: "DSM", href: "#", category: "NAS", }, ], Email: [ { id: 2, // 这里要把id改成唯一值,避免React渲染时key重复报错 name: "Webmail", href: "#", category: "Email", }, ], }); // 把所有分类的服务合并成一个一维数组 const allServices = Object.values(tabs).flat(); return ( <div> <Tab.Group> <Tab.List> {Object.keys(tabs).map((category) => (<Tab key={category}>{category}</Tab>))} </Tab.List> <Tab.Panels> {/* 每个标签页都渲染全部服务内容 */} {Object.keys(tabs).map((category, idx) => ( <Tab.Panel key={idx}> <ul role="list"> {allServices.map((service) => ( <li key={service.id}> <h3>{service.name}</h3> {/* 可选:显示分类信息,方便区分不同服务所属类别 */} <p>分类:{service.category}</p> </li> ))} </ul> </Tab.Panel> ))} </Tab.Panels> </Tab.Group> </div> ); }
关键改动说明:
- 新增
allServices变量,通过Object.values(tabs).flat()将各个分类下的服务数组合并成一个统一数组 - 标签页遍历逻辑改为基于
Object.keys(tabs),确保每个分类对应的标签页都保留,且每个标签页内部渲染allServices的全部内容 - 修正了原代码中两个服务id重复的问题,避免React渲染警告
内容的提问来源于stack exchange,提问作者Anan Kuntakam
相关产品推荐
相关产品推荐

