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

问题描述

在我的React应用程序中,我创建了一个名为添加产品页面,并带有一个名为 Add Variation 的按钮,以允许添加产品的小,中,大版本。如果用户改变了主意,就不会想出如何从状态中删除小型,中型或大型变型对象。

这是问题的摘要

enter image description here

以下是该组件的外观:

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表单,其中包含3个附加的删除变体按钮。不幸的是,我看不到如何告诉React#2项目在variations中的位置以将其删除,所以我求助于.pop()解决这个问题,这不是我想要的。

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

解决方法

如果我理解正确,则可以使用Arrray.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>

请记住,空白变体对象如下:

        { 
            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,vshipping: ""
        }]  
        let newV = oldV.concat(vPost);         
        setValues({
            ...values,variations: newV,error: ""
        })
    }

衷心的感谢,因为这让我头疼了数小时!