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

React电商项目创建商品接口如何传递嵌套对象与Tags数组

实现方案

按以下三步即可构造出符合后端要求的请求参数:

  • 补充表单状态定义,单独管理En嵌套对象的字段值
  • 给所有输入框绑定值更新事件,实时同步输入内容到状态
  • 提交表单时处理标签字段,把输入的字符串转成数组,拼接成后端要求的结构再发请求

具体修改点说明

  1. 状态调整
    保留原有的分类、集合、品牌状态,新增enProduct状态存储英文字段内容,标签输入阶段先存字符串,提交时再转数组。同时修正react-select的value绑定逻辑,之前只存id会导致选中后选项不回显。
  2. 输入框绑定
    给title、description、tags三个输入框加value和onChange属性,输入时实时更新对应状态。tags输入框增加提示,告知用户用英文逗号分隔多个标签。
  3. 提交逻辑处理
    拦截表单默认提交事件,先把tags输入的字符串按逗号分割、去除首尾空格、过滤空值得到标签数组,再按照后端要求的结构组装整个入参,调用接口发送即可。

修改后的完整代码

import { React, useState } from "react";
import {
  Col,
  Button,
  Form,
  FormGroup,
  Label,
  Input,
  FormText,
  Card,
  CardImg,
} from "reactstrap";
import { useCategories } from "../../../../hooks/useCategories";
import { useCollections } from "../../../../hooks/useCollections";
import { useBrand } from "../../../../hooks/useBrand";
import Select from "react-select";

const AddProduct = () => {
  const categories = useCategories();
  const collections = useCollections();
  const brands = useBrand();

  const categoriesOptions = categories?.data?.categories || [];
  const collectionsOptions = collections?.data?.collections || [];
  const brandsOptions = brands?.data?.brands || [];

  // 调整状态:react-select存整个选项对象保证回显,新增en相关字段状态
  const [category, setCategory] = useState(null);
  const [collection, setCollection] = useState(null);
  const [brand, setBrand] = useState(null);
  const [enProduct, setEnProduct] = useState({
    title: "",
    description: "",
    tagsInput: "" // 输入阶段存字符串,提交时转数组
  });

  // 统一处理en字段的输入更新
  const handleEnInputChange = (e) => {
    const { name, value } = e.target;
    setEnProduct(prev => ({
      ...prev,
      [name]: value
    }))
  }

  // 表单提交处理
  const handleSubmit = (e) => {
    e.preventDefault();
    // 处理tags数组:按逗号分割,去空格,过滤空值
    const tags = enProduct.tagsInput.split(',').map(tag => tag.trim()).filter(Boolean);
    // 组装后端要求的参数结构
    const createProductInput = {
      En: {
        title: enProduct.title,
        description: enProduct.description,
        tags: tags
      },
      category: category.id,
      collection: collection.id,
      brand: brand.id
    }
    // 这里替换成实际的GraphQL请求逻辑,把createProductInput传进去即可
    console.log("提交的参数:", createProductInput);
    // 请求参考写法:
    // createProduct({ variables: { createProductInput } })
  }

  return (
    <Card
      style={{
        boxShadow: "1px 1px 10px 1px #888888",
        borderRadius: "3rem",
        margin: "5rem",
        padding: "4rem",
      }}
    >
      <Form onSubmit={handleSubmit}>
        <h3 style={{ color: "black", fontWeight: "bold" }}>Add Product</h3>

        <div col>
          <img
            width="30%"
            height="40%"
            style={{
              paddingTop: "3rem",
              paddingBottom: "3rem",
              paddingRight: "3rem",
            }}
            src="https://themes.pixelstrap.com/multikart/back-end/assets/images/pro3/34.jpg"
            alt="Card image cap"
          />

          <div>
            <FormGroup row>
              <Label sm={2}>En:</Label>
              <Col sm={10}>
                <Input
                  type="text"
                  name="title"
                  id="title"
                  placeholder="title"
                  value={enProduct.title}
                  onChange={handleEnInputChange}
                />

                <Input
                  type="text"
                  name="description"
                  id="description"
                  placeholder="description"
                  style={{ marginTop: '0.7rem', marginBottom: '0.7rem'}}
                  value={enProduct.description}
                  onChange={handleEnInputChange}
                />

                <Input 
                  type="text" 
                  name="tagsInput" 
                  id="tags" 
                  placeholder="多个标签用英文逗号分隔"
                  value={enProduct.tagsInput}
                  onChange={handleEnInputChange}
                />
              </Col>
             
            </FormGroup>

        <FormGroup row>
          <Label for="exampleSelect" sm={2}>
            Select Collection
          </Label>
          <Col sm={10}>
            <Select
              value={collection}
              onChange={(selected) => setCollection(selected)}
              options={collectionsOptions}
              getOptionLabel={(e) => e.name}
              getOptionValue={(e) => e.id}
            />
          </Col>
        </FormGroup>

        <FormGroup row>
          <Label for="exampleSelect" sm={2}>
            Select Category
          </Label>
          <Col sm={10}>
            <Select
              value={category}
              onChange={(selected) => setCategory(selected)}
              options={categoriesOptions}
              getOptionLabel={(e) => e.name}
              getOptionValue={(e) => e.id}
            />
          </Col>
        </FormGroup>

        <FormGroup row>
          <Label for="exampleSelect" sm={2}>
            Select brands
          </Label>
          <Col sm={10}>
            <Select
              value={brand}
              onChange={(selected) => setBrand(selected)}
              options={brandsOptions}
              getOptionLabel={(e) => e.name}
              getOptionValue={(e) => e.id}
            />
          </Col>
        </FormGroup>
          </div>
        </div>
        <FormGroup check row>
          <Col sm={{ size: 10, offset: 2 }}>
            <Button type="submit">Submit</Button>
          </Col>
        </FormGroup>
      </Form>
    </Card>
  );
};

export default AddProduct;

补充说明:如果需要支持标签回车新增、删除单个标签的交互,可以把普通tags输入框换成react-select的多选模式,直接就能得到数组格式的tags值,不需要手动做字符串分割,逻辑会更简单。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:45:28