我正在做一个基本的react项目,在这个项目中,我使用了对象和数组来响应状态,我在这里要做的是把对象推到images数组中,我想在组件中呈现,到目前为止,我搜索了很少的方法来完成它-- array.concat和array.push,我尝试了这两种方法--它正在更新状态,但它对组件没有影响
下面是我尝试过的代码
const [proClrData, setProClrData] = useState([
{ color: "black", price: "", qty: "", images: [] },
{ color: "white", price: "", qty: "", images: [] },
{ color: "red", price: "", qty: "", images: [] }
]);
const addImages = (key) => {
var obj = { src: "", imgdata: "" };
proClrData[key].images = proClrData[key].images.concat(obj);
console.log(proClrData);
};下面是组件代码
{proClrData.length >= 1 &&
proClrData?.map((clr, key) => {
return (
<div key={key}>
<p className="pt-3 ">{clr.color}</p>
<div className="form-group">
<input
label="Price"
name="price"
value={clr?.price}
type="number"
fullWidth
required
/>
</div>
<div className="form-group pt-3">
<input
label="Quantity"
name="qty"
value={clr?.qty}
type="number"
fullWidth
required
/>
</div>
<div className="text-end pt-3">
<button
variant="contained"
color="primary"
onClick={() => addImages(key)}
>
Add Images
</button>
</div>
{clr?.images?.map((img, imgkey) => {
return (
<div className="form-group pt-3" key={imgkey}>
<input
label="Image"
name="images"
value=""
accept="image/*"
type="file"
fullWidth
required
/>
</div>
);
})}
</div>
);
})}这是工作代码的codeSandbox。
发布于 2021-07-09 07:12:23
问题
您正在更改状态对象,然后而不是更新状态。
const addImages = (key) => {
var obj = { src: "", imgdata: "" };
proClrData[key].images = proClrData[key].images.concat(obj); // mutation!!
console.log(proClrData);
};解决方案
将状态更新与所需的新图像数据连接到状态。使用功能状态更新从前一个状态进行更新。浅层复制proClrData数组,对于匹配的元素,也可以浅层复制它,因此它是一个新的对象引用,然后浅层复制嵌套的images数组并追加新的对象。
const [proClrData, setProClrData] = useState([
{ color: "black", price: "", qty: "", images: [] },
{ color: "white", price: "", qty: "", images: [] },
{ color: "red", price: "", qty: "", images: [] }
]);
const addImages = (key) => {
const obj = { src: "", imgdata: "" };
setProClrData(data => data.map((el, i) => i === key ? {
...el,
images: [...el.images, obj],
} : el));
};由于React状态更新是异步处理的,因此您将希望将控制台日志移动到useEffect钩子中,以便在状态更新后记录状态,并在下一次呈现时可用。
useEffect(() => {
console.log(proClrData);
}, [proClrData]);发布于 2021-07-09 07:12:14
您必须调用setProClrData函数来更新状态。
请记住,您不能改变状态,而是必须提供一个新的引用(在您的情况下是一个新的数组)并调用更新器函数,否则您的反应将不知道这是应该重新呈现组件。
const [proClrData, setProClrData] = useState([
{ color: "black", price: "", qty: "", images: [] },
{ color: "white", price: "", qty: "", images: [] },
{ color: "red", price: "", qty: "", images: [] }
]);
const addImages = (key) => {
const img = { src: "", imgdata: "" };
const newProClrData = proClrData.map((obj, index) => {
return index !== key ? data : { ...obj, images: [...data.images, img] };
});
setProClrData(newProClrData);
};发布于 2021-07-09 07:06:03
您应该相应地修改proClrData并使用setProClrData来触发重呈现。
https://stackoverflow.com/questions/68312545
复制相似问题