繁体   English   中英

如何在 React 中检查 object 数组是否存在于 state 中?

[英]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点要指出:

  • 你说你通过它创建了一个 object 和map来呈现输入字段。 实际上,你只能在JavaScriptmap超过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.

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