从数组中删除项React(无限重新渲染循环错误)



在一个小的React应用程序中,我试图通过一个列表按钮添加删除功能。目前,我正在尝试通过deleteItem函数,它利用数组。拼接原型方法。

然而,我遇到了错误,Too many re-renders. React limits the number of renders to prevent an infinite loop.。这个错误的原因是什么?这个函数不应该只在单击按钮时调用一次吗?

我该如何解决这个错误?

import "./styles.css";
import React, { useState, Fragment } from "react";
export default function App() {
  const [items, setItems] = useState(["first item"]);
  const [newItem, setNewItem] = useState("");
  const handleSubmit = (event) => {
    event.preventDefault();
    setItems([newItem, ...items]);
  };
  const handleChange = (event) => {
    setNewItem(event.target.value);
  };
  const deleteItem = (i) => {
    setItems(items.splice(i,1))
  }
  return (
    <div>
      <form>
        <input type="text" value={newItem} onChange={handleChange} />
        <input type="button" value="submit" onClick={handleSubmit} />
      </form>
      <ul>
        {items.map((i) => {
          return (
          <Fragment>
            <li>{i}</li>
              <button
                onClick= {() => deleteItem(i)}> // Amr recommendation
                delete 
              </button>
          </Fragment>
          );
        })}
      </ul>
    </div>
  );
}
编辑:我已经接受了用户Amr的推荐,并在按钮上添加了一个匿名箭头功能。然而,一个新的问题出现了。我可以删除任何项,直到数组中只存在一个项。最后一项不能删除。为什么会这样?

您正在传递onClick处理程序上的函数引用,将其更改为触发删除方法onClick= {()=>deleteItem(i)}> 的箭头函数

第二件事是,当你Map时,你应该为你的父组件添加键通过组件来防止不必要的行为。

和最后一件事是,在您的删除方法中,您正在使用Array.prototype.splice(),它返回将被删除的项目,从项目中,您请求/所需的行为可以通过Array.prototype.filter()方法

实现
  const deleteItem = (i) => {
    setItems(items.filter((item) => item !== i));
  };

这是最终结果,它应该可以正常工作。

import React, { useState, Fragment } from "react";
export default function App() {
  const [items, setItems] = useState(["first item"]);
  const [newItem, setNewItem] = useState("");
  const handleSubmit = (event) => {
    event.preventDefault();
    setItems([...items, newItem]);
  };
  const handleChange = (event) => {
    setNewItem(event.target.value);
  };
  const deleteItem = (i) => {
    setItems(items.filter((item) => item !== i));
  };
  console.log(items);
  return (
    <div>
      <form>
        <input type="text" value={newItem} onChange={handleChange} />
        <input type="button" value="submit" onClick={handleSubmit} />
      </form>
      <ul>
        {items.map((i, idx) => {
          return (
            <div key={idx}>
              <li>{i}</li>
              <button onClick={() => deleteItem(i)}>delete</button>
            </div>
          );
        })}
      </ul>
    </div>
  );
}

可以使用以下代码从数组中删除。它复制'items'数组并删除一个项目,然后setstate新数组。它可以防止重新渲染整个组件,对状态副本和setstate最终结果进行操作。

  const deleteItem = (i) => {
     let newItems=[...items]
     newItems.splice(i,1)
     setItems(newItems)
  };

最新更新