如何在React中结合MongoDB动态生成手风琴嵌套的按钮数组
解决方案
你可以通过对product.material做分组聚合后动态渲染手风琴结构实现需求,具体修改如下:
第一步:修复原有组件的小问题
你原有代码的useEffect在product未加载完成时就调用setCurrentSrc会触发报错,先调整逻辑,同时增加材质分组逻辑:
import {useEffect, useState} from "react"; import {useSelector, useDispatch} from "react-redux"; // Actions import {getProductDetails} from "../redux/actions/productActions"; const ProductScreen = ({match}) => { const dispatch = useDispatch(); const productDetails = useSelector((state) => state.getProductDetails); const {loading, error, product} = productDetails; const [currentSrc, setCurrentSrc] = useState(null); useEffect(() => { // 产品ID不匹配时重新拉取数据 if (match.params.id && (!product || match.params.id !== product._id)) { dispatch(getProductDetails(match.params.id)); } // 产品加载完成后再设置初始资源 if(product) { setCurrentSrc(product.src) } }, [dispatch, match, product]); const changeColor = (event) => { const modelViewer = document.querySelector("model-viewer"); modelViewer.variantName = event.target.value; }; // 新增:按材质分类聚合数据 const materialGroups = product?.material?.reduce((groups, item) => { const category = item.category; // 替换为你MongoDB中存储分类的字段名 if (!groups[category]) groups[category] = []; groups[category].push(item); return groups; }, {}) || {}; // 加载/错误状态处理 if(loading) return <div>加载中...</div> if(error) return <div>加载失败:{error}</div> if(!product) return <div>产品不存在</div> return ( {/* 其余原有页面代码 */} {/* 替换原来硬编码的手风琴部分 */} <div className="accordion"> {Object.entries(materialGroups).map(([category, materials]) => ( <div key={category}> <input type="radio" name="accordion" id={category} className="accordion__input" /> <label htmlFor={category} className="materialLabel"> {category} </label> <div className="items"> {materials.map(material => ( <button key={material.name} // 替换为你MongoDB中存储材质名称的字段名 onClick={changeColor} className='item' value={material.name} > {material.name} </button> ))} </div> </div> ))} </div> {/* 其余原有页面代码 */} ) }
注意事项
- 代码里的
category和name字段需要和你MongoDB里存储的材质字段名对应,如果你存的是别的字段名直接替换即可 - 如果你的接口返回的材质数据本身已经是按分类分组的结构,直接遍历分组即可,不需要额外做reduce聚合
内容的提问来源于stack exchange,提问作者Wade Morrison
相关产品推荐
相关产品推荐

