繁体   English   中英

React - 如何从 state 中删除数组项?

[英]React - How do I remove array item from state?

在我的 react 应用程序中,我创建了一个名为Add Product的页面,其中包含一个名为Add Variation的按钮,以允许添加产品的小、中、大变体,但不知道如何从 object 中删除小、中或大变体state 如果用户改变主意。

这是问题的摘要: 在此处输入图像描述

这是组件现在的样子:

const AddProduct = () => {
    const [addVar, setAddVar] = useState(0)
    const [values, setValues] = useState({
        name: "",
        description: "",
        categories: [],
        category: "",
        photo: "",
        loading: false,
        error: "",
        createdProduct: "",
        redirectToProfile: false,
        variations: [],
        formData: ""
    });

    const {
        name,
        description,
        price,
        categories,
        category,
        photo,
        loading,
        error,
        createdProduct,
        redirectToProfile,
        variations,
        formData
    } = values;

    const addVariation = (e) => {
        e.preventDefault()
        setAddVar(addVar + 1)
        let oldV = Array.from(variations); // gets current variations
        let n = oldV.length; // get current array position
        console.log(`Current number of variations is: ${n}`);
        let vPost = [{ 
            number: n,
            vname: "",
            vprice: "",
            vquantity: "",
            vshipping: ""
        }]  
        let newV = oldV.concat(vPost);         
        setValues({
            ...values,
            variations: newV,
            error: ""
        })
    }   

    const handleVariationChange = (name, numberVal) => event => {
        // numberVal is the iteration number
        // name is the variation property which can be vname, vprice, vshipping, vquantity
        // these are tested next in the following if statements
        const value = event.target.value;
        console.log(`numberVal: `, numberVal);
        event.preventDefault()
        let newVariations = Array.from(variations)
                
        if(name === "vname") { 
            newVariations[numberVal].vname = value;
            console.log(`newVariations[numberVal].vname value: `, newVariations)
        }

        if(name === "vprice") { 
            newVariations[numberVal].vprice = value;
            console.log(`newVariations[numberVal].vprice value: `, newVariations)
        }

        if(name === "vshipping") { 
            newVariations[numberVal].vshipping = value;
            console.log(`newVariations[numberVal].vshipping value: `, newVariations)
        }

        if(name === "vquantity") { 
            newVariations[numberVal].vquantity = value;
            console.log(`newVariations[numberVal].vquantity value: `, newVariations)            
        }
        
        setValues({...values, variations: newVariations})
        formData.set("variations", JSON.stringify(newVariations));
    };

    const removeVariation = (e) => {
        e.preventDefault()
        let newVariations = Array.from(variations)
        let popped = newVariations.pop()
        
        setValues({
            ...values,
            variations: newVariations,
            error: ""
        })
        
    }

    const newPostForm = () => (
        <form className="mb-3" onSubmit={clickSubmit}>
            <h4>Main Photo</h4>
            <div className="form-group">
                <label className="btn btn-secondary">
                    <input
                        onChange={handleChange("photo")}
                        type="file"
                        name="photo"
                        accept="image/*"
                    />
                </label>
            </div>
            <div className="form-group">
                <label className="text-muted">Main Product Name</label>
                <input
                    onChange={handleChange("name")}
                    type="text"
                    className="form-control"
                    value={name}
                    placeholder="Add main product name"
                />
            </div>
            <div className="form-group">
                <label className="text-muted">Description</label>
                <textarea
                    onChange={handleChange("description")}
                    className="form-control"
                    value={description}
                    placeholder="Add description"
                />
            </div>         
            <div className="form-group">
                <label className="text-muted">Category</label>
                <select
                    onChange={handleChange("category")}
                    className="form-control"
                >
                    <option>Please select</option>
                    {categories &&
                        categories.map((c, i) => (
                            <option key={i} value={c._id}>
                                {c.name}
                            </option>
                        ))}
                </select>
            </div>
            <div>
                    <button onClick={addVariation}>Add variation</button>
                    </div>
                    {variations ? VariationComponent() : null}
            <br />
            <br />
            <button type="submit" className="btn btn-outline-primary">Create Product</button>
        </form>
    );

return (
        <Layout>
            <div className="row">
                <div className="col-md-8 offset-md-2">
                    {newPostForm()}                    
                </div>
            </div>
        </Layout>
    );
};

export default AddProduct;

每次单击添加变体时,页面都会附加另一个VariationComponent表单。 例如,如果单击“添加变体”按钮 3 次,则会生成 3 个VariationComponent forms 并附加 3 个移除变体按钮。 不幸的是,我不知道如何告诉 React 变体中#2 项目的variations以将其删除,因此我求助于使用.pop()解决这个问题,这不是我想要的。

单击“删除变体”按钮时,如何告诉 React 删除正确的数组项?

如果我理解正确,您可以使用 Array.filter() 确定要删除的变体。 它返回一个新数组,除了匹配的 numberVal 之外的所有数组。

onClick={e=>removeVariation(e)}

const removeVariation = e => {
  e.preventDefault();

  setValues({
    ...values,
    variations: variations.filter(item => item.name !== e.target.value),
    error: ''
  });
};

感谢@RobinZigmond 和@7iiBob 的回答,我能够通过以下代码解决这个问题:

    const removeVariation = (e, num) => {
        e.preventDefault();
      
        setValues({
          ...values,
          variations: variations.filter(item => item.number !== num),
          error: ''
        });
      };

移除变化按钮:

<button onClick={(e) => removeVariation(e, variations[i].number)} className="btn-danger">
    {`Remove Variation`}
</button>

请记住,空变体 object 如下所示:

        { 
            number: n,
            vname: "",
            vprice: "",
            vquantity: "",
            vshipping: ""
        }

n来自addVariation这里:

    const addVariation = (e) => {
        e.preventDefault()
        setAddVar(addVar + 1)
        let oldV = Array.from(variations); // gets current variations
        let n = oldV.length; // get current array position
        console.log(`Current number of variations is: ${n}`);
        let vPost = [{ 
            number: n,
            vname: "",
            vprice: "",
            vquantity: "",
            vshipping: ""
        }]  
        let newV = oldV.concat(vPost);         
        setValues({
            ...values,
            variations: newV,
            error: ""
        })
    }

衷心感谢您,因为这让我头痛了好几个小时!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM