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

如何解构JSON数组>对象>数组并在React组件中渲染对应商品

解决JSON数据解构与分类商品渲染问题

问题背景

需要解构如下结构的JSON文件,获取"Bags"、"Shoes"这类分类名称,并根据传入的merch参数渲染对应分类的商品:

[
  {
    "Bags": [
      {
        "id": 1,
        "name": "Michael Kors Bag",
        "price": 235,
        "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
      },
      {
        "id": 2,
        "name": "Ted Baker Bag",
        "price": 495,
        "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
      },
      {
        "id": 3,
        "name": "Coach Bag",
        "price": 238,
        "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
      },
      {
        "id": 4,
        "name": "Kate Spade Bag",
        "price": 35,
        "imgURL": "/imgs/10.jpg"
      }
    ]
  },
  {
    "Shoes": [
      {
        "id": 1,
        "name": "Michael Kors Bag",
        "price": 235,
        "imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
      },
      {
        "id": 2,
        "name": "Ted Baker Bag",
        "price": 495,
        "imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
      },
      {
        "id": 3,
        "name": "Coach Bag",
        "price": 238,
        "imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
      },
      {
        "id": 4,
        "name": "Kate Spade Bag",
        "price": 35,
        "imgURL": "/imgs/10.jpg"
      }
    ]
  }
]

路由传入参数的方式如下:

<Route path="/store" element={<Store merch="Bags" />} />

当前的Store.tsx无法正常工作,代码如下:

import storeItems from "../data/items.json";
import { Row, Col, Container } from "react-bootstrap";
import { StoreItem } from "../components/StoreItem";
import { useState } from "react";

type StoreProps = {
  merch: string;
};

export function Store({ merch }: StoreProps) {
  const [data, setData] = useState([]);
  for (let i = 0; i < storeItems.length; i++) {
    let a = Object.values(storeItems[i]);
    console.log(a);
  }
  console.log(storeItems);
  return (
    <>
      <Container className="mw-80 d-flex align-items-center justify-content-center p-0 flex-column mb-5">
        <h1 className="m-5">Bags</h1>
        <Row md={2} xs={1} lg={3} className="g-3">
          {storeItems.map((item) => (
            <Col>
              <StoreItem key={item.id} {...item} />
            </Col>
          ))}
        </Row>
      </Container>
    </>
  );
}

解决方案

1. 理解JSON结构

原始JSON是一个数组,每个元素是单键对象:键为分类名称(如"Bags"),值为对应分类的商品数组。需要根据merch参数匹配这个键,取出对应的商品列表。

2. 优化Store组件实现

不需要使用useState存储静态数据,直接在组件中计算出目标分类的商品即可,修改后的代码如下:

import storeItems from "../data/items.json";
import { Row, Col, Container } from "react-bootstrap";
import { StoreItem } from "../components/StoreItem";

type StoreProps = {
  merch: string;
};

// 定义商品类型,提升类型安全性
type Product = {
  id: number;
  name: string;
  price: number;
  imgURL: string;
};

export function Store({ merch }: StoreProps) {
  // 找到对应分类的商品数组
  const products: Product[] = storeItems
    // 遍历数组,找到包含目标分类键的对象
    .find(item => Object.keys(item).includes(merch))
    // 取出该分类下的商品列表,若无匹配则返回空数组
    ?.[merch] || [];

  return (
    <>
      <Container className="mw-80 d-flex align-items-center justify-content-center p-0 flex-column mb-5">
        {/* 动态渲染分类标题 */}
        <h1 className="m-5">{merch}</h1>
        <Row md={2} xs={1} lg={3} className="g-3">
          {/* 遍历商品数组渲染StoreItem */}
          {products.map((product) => (
            <Col key={product.id}>
              <StoreItem {...product} />
            </Col>
          ))}
        </Row>
      </Container>
    </>
  );
}

关键修改点

  • 移除了不必要的useState,直接通过find方法匹配目标分类
  • 添加了Product类型定义,增强TypeScript类型检查
  • 动态渲染分类标题(替换了硬编码的"Bags")
  • 遍历对应分类的商品数组,而非原始的storeItems数组,确保只渲染目标分类的商品
  • 处理了无匹配分类的情况,默认返回空数组避免报错

内容的提问来源于stack exchange,提问作者ether

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:45:53