React电商项目创建商品接口如何传递嵌套对象与Tags数组
实现方案
按以下三步即可构造出符合后端要求的请求参数:
- 补充表单状态定义,单独管理
En嵌套对象的字段值 - 给所有输入框绑定值更新事件,实时同步输入内容到状态
- 提交表单时处理标签字段,把输入的字符串转成数组,拼接成后端要求的结构再发请求
具体修改点说明
- 状态调整
保留原有的分类、集合、品牌状态,新增enProduct状态存储英文字段内容,标签输入阶段先存字符串,提交时再转数组。同时修正react-select的value绑定逻辑,之前只存id会导致选中后选项不回显。 - 输入框绑定
给title、description、tags三个输入框加value和onChange属性,输入时实时更新对应状态。tags输入框增加提示,告知用户用英文逗号分隔多个标签。 - 提交逻辑处理
拦截表单默认提交事件,先把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
相关产品推荐
相关产品推荐

