从react.js中的对象数组中删除索引总是会删除最后一个索引

时间:2019-03-01 01:14:17

标签: javascript arrays reactjs object splice

我在从react.js中的对象数组中删除索引时遇到问题。

我有一个表,该表显示该状态的数据的名称和值。每行都有一个删除它的按钮,它可以工作。

还有另一个按钮,可在数组中推送HTML输入的新对象,以便用户添加新值。 我这里的问题是删除按钮。如果我添加2或3行,则删除按钮将始终删除最后一行。

我不确定删除按钮为何不起作用。

如果有人可以提供帮助,我深表感谢。

这是代码:

class App extends Component {
  constructor(props) {
  super(props);
  this.state = {
    datas: [
      { name: 'test', value: 'test' },
      { name: 'test 1', value: 'test 1' }
    ]
  }
}

delete = (index) => {
  let datas = this.state.datas.filter((e, i) => i !== index);
  this.setState({ datas : datas });
}

addnew = () => {
  let datas = this.state.datas;
  datas.push( {name: <input />, value: <input /> })
  this.setState({ datas : datas });
}

render() {
  return (
    <div>
      <button onClick={this.addnew}>Add</button>
      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Value</th>
            <th>Action</th>
          </tr>
        </thead>
        <tbody>
          {this.state.datas.map((data, index) => (
            <tr key={index}>
              <th>{data.name}</th>
              <th>{data.value}</th>
              <th><button onClick={() => this.delete(index)}>delete</button>                  </th>
          </tr>
         ))}
        </tbody>
      </table>
    </div>
  );
}}
export default App;

3 个答案:

答案 0 :(得分:0)

添加行时,将初始值设置为输入元素。比删除时要查找包含输入元素的对象的数组索引。函数indexOf返回出现的第一个索引。

更好的解决方案是更新删除按钮以传递要删除的元素的索引

            <th><button onClick={() => this.delete(index)}

不仅仅是删除函数中具有给定索引的元素。

delete = (index) => {
    let datas = this.state.datas.filter((e, i) => i !== index);
    this.setState({ datas : datas });
  }

但是那仍然不能完全解决您的解决方案,因为您正在设置新的数组元素来容纳输入元素。你不应该的。

答案 1 :(得分:0)

我认为,问题在于使用map的索引作为键。您可以在每个项目本身中拥有一个index属性。

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      datas: [
        { index:0, name: "test", value: "test" },
        { index:1, name: "test 1", value: "test 1" },
        { index:2,  name: "test 2", value: "test 2" }
      ],
      counter: 3
    };
  }

  delete = index => {
    let datas = this.state.datas.filter((e, i) => i !== index);
    this.setState({ datas: datas });
  };

  addnew = () => {
    let datas = this.state.datas;
    datas.push({ index: this.state.counter, name: <input />, value: <input /> });
    this.setState({ datas: datas, counter: this.state.counter + 1 });
  };

  render() {
    return (
      <div>
        <button onClick={this.addnew}>Add</button>
        <table>
          <thead>
            <tr>
              <th>Name</th>
              <th>Value</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            {this.state.datas.map((data, index) => (
              <tr key={data.index}>
                <th>{data.name}</th>
                <th>{data.value}</th>
                <th>
                  <button onClick={() => this.delete(index)}>delete</button>{" "}
                </th>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  }
}

在CodeSandbox上编辑:https://codesandbox.io/embed/p57now4pjx?fontsize=14

答案 2 :(得分:0)

一个简单的解决方案是在组件上设置唯一的key。为此,请尝试将表分成不同的组件,例如<Row /><Col />,然后在这些组件上设置唯一键,例如:<Row key={"uniqKey1"} onClick={() => this.delete(index) />

那么它肯定会删除该组件。