首页 > 解决方案 > React 状态钩子变量与 ui 不一致

问题描述

我有一个反应应用程序,它使用状态挂钩来跟踪列表中有多少项目。当我从列表中删除项目时,UI 会更新,但底层元素数组仍会显示所有元素。这是一个演示该问题的代码框。

// App.js

export default function App() {
  const handleRemoveRow = (i) => {
    console.log("state array: " + feesArray);
    console.log("index to remove: " + i);
    setFeesArray(
      feesArray.filter((_, index) => {
        console.log("filtering index: " + index);
        return index !== i;
      })
    );
  };

  const [feesArray, setFeesArray] = useState([
    <ListItem handleRemoveRow={handleRemoveRow} index={0} key={0} />,
    <ListItem handleRemoveRow={handleRemoveRow} index={1} key={1} />,
    <ListItem handleRemoveRow={handleRemoveRow} index={2} key={2} />
  ]);

  return (
    <>
      <ul>{feesArray}</ul>
    </>
  );
}
// ListItem.js

export default function ListItem(props) {
  return (
    <li>
      <IconButton
        onClick={() => {
          props.handleRemoveRow(props.index);
        }}
      >
        <CloseIcon />
      </IconButton>
    </li>
  );
}

https://codesandbox.io/s/sleepy-leakey-zewrb?file=/src/App.js

如果您尝试通过单击“x”来删除项目,您将看到一行被删除,但底层数组将保留为 3 个项目,并且不允许删除更多项目。提前致谢。

标签: reactjsreact-hooksmaterial-uistate

解决方案


您将indexprop 静态传递给 ListItem,但在尝试删除元素时使用数组中的相对索引。

所以一开始,indexprop 匹配数组中的索引:

[
    <ListItem handleRemoveRow={handleRemoveRow} index={0} key={0} />, // Array index 0
    <ListItem handleRemoveRow={handleRemoveRow} index={1} key={1} />, // Array index 1
    <ListItem handleRemoveRow={handleRemoveRow} index={2} key={2} /> // Array index 2
]

这就是为什么您可以在第一次删除它的原因。但是假设您删除索引 1,您的数组将变为:

[
    <ListItem handleRemoveRow={handleRemoveRow} index={0} key={0} />, // Array index 0
    <ListItem handleRemoveRow={handleRemoveRow} index={2} key={2} /> // Array index 1
]

然后,如果您尝试删除带有 的index={2}那个,它将尝试在数组中找到位置 2,该位置不再存在。

我假设您正在尝试在数组中呈现动态数据。我建议您将数据与 ListItem 组件的呈现分开,如下所示:

  const [feesArray, setFeesArray] = useState([
    { value: "a" },
    { value: "b" },
    { value: "c" }
  ]);

  return (
    <>
      <ul>
        {feesArray.map((fee, i) => (
          <ListItem handleRemoveRow={handleRemoveRow} key={i} index={i} />
        ))}
      </ul>
    </>
  );

工作代码框:

https://codesandbox.io/s/little-monad-cqqsh?file=/src/App.js:389-679


推荐阅读