[英]How to check if array of object exist in state in React?
我正在使用 React JS 构建动态表单。 在我的一个表单中,我创建了一个 10 的输入表单。为了获得干净的代码,我通过它为表单创建了一个 object 和 map。 代码如下。
{homeAmeneties.map((home) => {
<div className="h-8 flex justify-end rounded-md pr-10">
<input
type="number"
onInput={(event) =>
(event.target.value = event.target.value.slice(
0,
event.target.maxLength
))
}
maxLength="3"
onChange={(e) => updateVal(e, home.name)}
className="border-[1px] w-1/2 border-black rounded-md h-full focus:outline-none px-2"
/>
</div>
})}
然后我创建了一个useState([])
并使用条件检查该字段是否存在,以便我只能更新该值。
const [amen, setAmen] = useState([]);
const updateVal = (e, type) => {
amen.some((item) => {
if (item.name === type) {
setAmen({ name: type, val: e.target.value });
} else {
setAmen({ name: type, val: e.target.value });
}
});
}
当我运行它时它会抛出一个错误。 amen.some is not a function
错误。 我想要实现的是,最初 state 是空的。 但是当一个字段值更改时,它会将其作为{ name: type, val: e.target.value }
添加到数组中。 所以在添加之前我们检查类型是否已经存在。 如果是这样,那么我们更改 object 的确切数组的值。但如果类型不存在,它会创建一个新的 object。我该怎么做?
看起来错误被抛出是因为 amen 是一个数组,但你试图在它上面使用 .some() 方法,这是 Array 原型的一个方法,但它不是 function。.some() 返回boolean 而不是数组,因此您不能将其他数组方法链接到它。
要实现您想要的效果,您可以改用 .findIndex() 方法。 此方法返回数组中满足提供的测试 function 的第一个元素的索引,如果未找到,则返回 -1。
以下是如何使用 .findIndex() 方法更新 state 的示例:
const updateVal = (e, type) => {
const index = amen.findIndex((item) => item.name === type);
if (index !== -1) {
const newAmen = [...amen];
newAmen[index] = { name: type, val: e.target.value };
setAmen(newAmen);
} else {
setAmen([...amen, { name: type, val: e.target.value }]);
}
};
这段代码首先在amen数组中找到object的索引,该索引的name属性与传入的类型匹配。如果索引不为-1,则表示object已经存在于数组中,因此创建一个新数组(newAmen) 即当前state数组的副本,更新索引处object的值,并将新数组设置为新的state。如果索引为-1,则表示object不存在数组,因此它会创建一个新数组,其中包含新的 object,并将其设置为新的 state。
此外,在您的代码中,您试图将 state 设置为 object,而这不是 state 的工作方式。 在您的情况下,您尝试将 state 设置为 object,但它需要一个数组,这就是它抛出错误的原因。
你应该使用setAmen(prevAmen => [...prevAmen, { name: type, val: e.target.value }]);
const updateVal = (e, type) => {
const index = amen.findIndex((item) => item.name === type);
if (index !== -1) {
setAmen((prevAmen) => {
prevAmen[index] = { name: type, val: e.target.value };
return [...prevAmen];
});
} else {
setAmen((prevAmen) => [...prevAmen, { name: type, val: e.target.value }]);
}
};
这样它应该按预期工作。
我有3
点要指出:
map
来呈现输入字段。 实际上,你只能在JavaScript
中map
超过arrays
。updateVal
方法调用中,您将react state
设置为object
而不是array
。Array.some ()
来更新 state。相反,我会使用Array.findIndex ()
。const updateVal = (e, type) => {
const updatedAmen = [ ...amen ]; // create a new array to avoid mutating the state directly
// check if an input already exists with the said type & get the index position
const exisitingAmenIdx = updatedAmen.findIndex((a) => a.name === type);
if (exisitingAmenIdx >= 0) {
updatedAmen[exisitingAmenIdx].val = e.target.value;
} else {
updatedAmen.push({
name: type,
val: e.target.value
})
// finally update the state
setAmen(updatedAmen)
}
};
这是因为您将amen
的 state 值设置为 object,您的目标是 append 到数组:
setAmen({ name: type, val: e.target.value });
// amen = { name: type, val: e.target.value }
由于它从 Array 变为Array
,因此不会定义Array.some()
。 您可以拨打 go 的一种方法是:
setAmen([{ name: type, val: e.target.value }, ...amen]);
创建一个新数组,因此 React 将更新 state。添加新元素,然后使用扩展运算符...amen
提取其他元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.