【发布时间】:2020-08-15 18:03:26
【问题描述】:
在我的 react 应用程序中,我创建了一个名为 Add Product 的页面,其中包含一个名为 Add Variation 的按钮,以允许添加产品的小型、中型、大型变体,但可以'不知道如果用户改变主意,如何从状态中删除小、中或大的变化对象。
这是组件现在的样子:
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 个带有 3 个附加的 删除变体 按钮的 VariationComponent 表单。不幸的是,我不知道如何告诉 React variations 中 #2 项目的位置来删除它,所以我求助于 .pop() 解决这个问题,这不是我想要的。
当点击Remove Variation按钮时,如何告诉React删除正确的数组项?
【问题讨论】:
-
一般来说,当你想删除给定索引处的元素时,使用splice 而不是
pop。但我真的很难理解你的代码是如何工作的。在几个地方,您引用了似乎未定义的variations变量 - 相关数组仅作为values状态对象的属性存在。 -
实际上,不是
splice发生变异(pop也是如此),您最好使用filter返回一个新数组,该数组缺少具有所需索引的数组。 -
@RobinZigmond 我很抱歉,第二次看时我意识到我遗漏了我解构状态值并使它们在范围内可用的部分。请再次查看我的更新答案。
-
@RobinZigmond 好的,我在
filter和你在一起,但我将如何在这里使用它?如果我更改按钮并像这样传递i,则会引发错误。事实上,我一直无法用参数调用处理程序,这就是我卡住的地方。我想过滤但还不能解决如何通过位置。 -
如果我错了,请纠正我,但您似乎有一个“删除”按钮,可以删除您拥有的三个“变体”中的任何一个。对于将索引映射到您的
removeVariation函数的每个“变体”可能有一个“删除”按钮似乎更合适,您的 onClick 处理程序可能看起来像<button onClick={() => removeVariation(i)}>Remove variation</button>
标签: javascript node.js reactjs jsx