javascript - 如何在不删除数组其余部分的情况下从 React 状态数组中删除组件?

标签 javascript arrays reactjs react-hooks state

我做了一个基本的应用程序来练习 React,但我很困惑为什么当我尝试从状态数组中删除单个组件时,它之后的所有项目也被删除了。这是我的基本代码:

应用程序.js:

import React from 'react' 
import Parent from './Parent';
import './App.css';

function App() {
  return (
    <div className="App">
      <Parent />
    </div>
  );
}

export default App;

Parent.js:

import React, { useState } from 'react';
import ListItem from './ListItem';
import './App.css';

function Parent() {
  const [itemList, setItemList] = useState([])
  const [numbers, setNumbers] = useState([])

  const addItem = () => {
    const id = Math.ceil(Math.random()*10000)
    const newItem = <ListItem 
      id={id}
      name={'Item-' + id}
      deleteItem={deleteItem}
    />
    const list = [...itemList, newItem]
    setItemList(list)
  };

  const deleteItem = (id) => {
    let newItemList = itemList;
    newItemList = newItemList.filter(item => {
        return item.id !== id
    })
    setItemList(newItemList);
  }

  const addNumber = () => {
    const newNumbers = [...numbers, numbers.length + 1]
    setNumbers(newNumbers)
  }

  const deleteNum = (e) => {
    let newNumbers = numbers
    newNumbers = newNumbers.filter(n => n !== +e.target.innerHTML)
    setNumbers(newNumbers);
  }

  return (
    <div className="Parent">
      List of items:
      <div>
        {itemList}
      </div>
      <button onClick={addItem}>
        Add item
      </button>
      <div>
        List of numbers:
        <div>
          {numbers.map(num => (
            <div onClick={deleteNum}>{num}</div>
          ))}
        </div>
      </div>
      <button onClick={addNumber}>
        Add number
      </button>
    </div>
  );
};

export default Parent;

ListItem.js:

import React from 'react';
import './App.css';

function ListItem(props) {

  const { id, name, deleteItem } = props;

  const handleDeleteItem = () => {
    deleteItem(id);
  }

  return (
    <div className="ListItem" onClick={handleDeleteItem}>
      <div>{name}</div>
    </div>
  );
};

export default ListItem;
  1. 当我通过单击按钮添加项目时,父状态会正确更新。
  2. 当我单击该项目(将其删除)时,它会删除自身以及数组中出现在它之后的所有项目 <-- 不良行为。我只想删除特定项目。
  3. 我也用数字测试过它(没有创建单独的组件)。这些删除正确 - 只有我点击的个人号码被删除。

据我所知,各个项目组件都保存了一个关于创建它们时父状态值的引用。这对我来说似乎是非常奇怪的行为......

当 itemList 状态数组由单独的组件组成时,如何仅删除单个项目?

谢谢

编辑:根据 Bergi 的指示,我通过将“itemList”状态值转换为对象数组以在列表更改时呈现(和重新呈现)来解决此问题:

    const addItem = () => {
      const id = Math.ceil(Math.random()*10000);
      const newItem = {
        id: id,
        name: 'Item-' + id,
      }
      const newList = [...itemList, newItem]
      setItemList(newList)
    }

...

    React.useEffect(() => {

    }, [itemList]);

...

<div className="Parent">
    List of items:
    <div>
        {itemList.map(item => {
        return (<ListItem
            id={item.id}
            name={item.name}
            deleteItem={deleteItem}
        />);
    })}
...

最佳答案

问题是您的 deleteItem 函数是旧 itemList 的闭包,从项目创建的那一刻开始。两种解决方案:

  • 使用setItemList的回调形式
  • 不要在该列表中存储 react 元素,而只是普通对象(您可以将其用作 Prop )并仅在呈现 ListItem< 时传递(最新的)deleteItem 函数s

关于javascript - 如何在不删除数组其余部分的情况下从 React 状态数组中删除组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65265839/

相关文章:

javascript - k6脚本: How to parse file info to use in HTTP query

javascript - 未捕获的类型错误 : Cannot read property 'propeller' of undefined

c - 使用函数查找数组中的最小值?

PHP 多维数组操作

python - numpy pad 是如何实现的(对于常量值)

javascript - 在ReactJS中改变背景图片

reactjs - 无状态函数组件不能有引用

javascript - 如何从 Angular 4的mbd-select中获取数据

javascript - 如何更改 html 页面中每次出现的特定字符的颜色? (例如 '*' )

javascript - 在 React Typescript 中,如何定义原生 html 元素的 ...rest 参数的类型?