You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 23:36:09