从React数组中删除项目

4

我在removeItem函数上遇到了问题(它应该删除当前嵌套在其中的按钮的<li>以及此.state.list中的项),目前没有代码,因为我尝试了很多方法,但什么都不起作用,所以最终我只能通过console.logs来观察发生了什么,然后删除了它。

import React, { Component } from 'react';
import './Todo.css';

class Todo extends Component {
    constructor(props) {
        super(props);
        this.state = {
            list: [],
            text: ''
        }
        this.textChange = this.textChange.bind(this);
        this.addToList = this.addToList.bind(this);
        this.removeItem = this.removeItem.bind(this);
    }

    textChange(e) {
        this.setState({
            text: e.target.value
        })
    }

    addToList() {
        this.setState(prevState => ({
            list: prevState.list.concat(this.state.text),
            text: ''
        }))
    }

    removeItem(e) { ?
        ? ? ? ? ? ? ?
    }

    render() {
        return(
          <div>
            <h1>My Todo List</h1>
            <h3>Add item</h3>
            <input value={this.state.text} onChange={e => this.textChange(e)}/>
            <button onClick={this.addToList}>+</button>
            <ul>{this.state.list.map((x,y) => {
              return <li key={y}>{x}
              <button onClick={this.removeItem}>-</button>
              </li>})}
            </ul>
          </div>
        )
    }
}

export default Todo;

1
从状态中获取数组并使用splice函数删除元素,然后设置状态。 - sarthak
1
可能是重复问题 在React中从状态数组中删除项目 - margaretkru
8个回答

14

在我的解决方案中 例如:

const remove = (i) => {
        const arr = data.filter((item) => item.name !== i);
        setData(arr);
    };

我筛选了那些未被移除的项目,并重新设置了状态。


3
虽然这段代码可以解决问题,但它没有解释为什么或者如何回答这个问题。请在您的代码中包含解释,因为这真的有助于提高贴子的质量。请记住,您正在回答未来读者的问题,而这些人可能不知道您的代码建议原因。您可以使用“编辑”按钮来改进此答案以获取更多投票和声望! - Brian Tompsett - 汤莱恩
对不起,这是我的错! - Hải Anh Nguyễn

8
从数组中按索引删除项目:
const newList = this.state.list.splice(index, 1);

从数组中按值删除元素:
const newList = this.state.list.splice(this.state.list.indexOf(value), 1);

2
我认为你在这里想使用 splice。但是即使如此,splice 直接改变了数组,这在 React 中通常是不被赞同的。 - BMiner
是的,它是splice而不是slice!这是两个不同的函数。 - JeremyF

3

您可以通过想要的问题筛选列表,列表将自动被移除, 例如,如果您想删除所有项目= 3 :

列表:prevState.list.filter(x=> x != 3);

祝您好运!


2
removeItem(item) {
    const item = getItem(this.state.list, item.id) // Method to get item in list through comparison (IE: find some item with item.id), it has to return ITEM and INDEX in array
    const newlist = [].concat(list) // Clone array with concat or slice(0)
    newlist.splice(item.index, 1);
    this.setState({list: newlist});       
  }

2

我认为您应该将项目的索引传递给removeItem函数。如下所示:

removeItem(index) {
  const list = this.state.list;

  list.splice(index, 1);
  this.setState({ list });
}

render() {
  return(
    <div>
      <h1>My Todo List</h1>
      <h3>Add item</h3>
      <input value={this.state.text} onChange={e => this.textChange(e)}/>
      <button onClick={this.addToList}>+</button>
      <ul>{
        this.state.list.map((text, i) => {
          return (
            <li key={i}>
              {text}
              <button onClick={() => this.removeItem(i) }>-</button>
            </li>
          );
        })}
      </ul>
    </div>
  )
}

这个程序总是删除我的待办事项列表中的第一项,所以如果我想要删除最后一项,它会删除第一项。它不起作用。 - Dave Wicomo
很抱歉,但实际上它是有效的,我错过了render()的一部分,请谅解。 - Dave Wicomo

1

当点击时,我会传递列表中项目的索引,然后对数组进行切片:

<ul>
  {
    this.state.list.map((x,y) => {
      return (
        <li key={y}>
          {x}
          <button onClick={() => this.removeItem(y)}>-</button>
        </li>
      );
    })
  }
</ul>

然后在removeItem函数中:
removeItem(index) {
  const list = this.state.list;
  list.splice(index, 1);
  this.setState({ list });
}

也许可以这样:list.splice(index, 1); - Kvlknctk

0

import React, { Component } from 'react';
import './Todo.css';

class Todo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [],
      text: ''
    }
    this.textChange = this.textChange.bind(this);
    this.addToList = this.addToList.bind(this);
  }

  textChange(e) {
    this.setState({
      text: e.target.value
    })
  }

  addToList() {
    this.setState(prevState => ({
      list: prevState.list.concat(this.state.text),
      text: ''
    }))
  }

  removeItem(index) {
    let newList = this.state.list.splice(index,1);
    this.setState({list:newList})
  }

  render() {
    return(
      <div>
        <h1>My Todo List</h1>
        <h3>Add item</h3>
        <input value={this.state.text} onChange={e => this.textChange(e)}/>
        <button onClick={this.addToList}>+</button>
        <ul>{this.state.list.map((x,y) => {
          return <li key={y}>{x}
          <button onClick={this.removeItem.bind(this,y)}>-</button>
          </li>})}
        </ul>
      </div>
    )
  }
}

export default Todo;


这个程序删除了几个列表项,无论你按哪一个都会被删除,所以它不起作用。 - Dave Wicomo
请再检查一次,确保它实际上是有效的,因为我正在传递特定数组项的索引。谢谢,@DaveWicomo。 - yogesh agrawal

0
  _deleteTodo(index) {
    console.log("delete " + index);
    this.state.todos.splice(index, 1);
    this.setState({
      todos: this.state.todos.filter(i => i !== index)
    });
  }

我在使用splice时遇到了问题,但是这种方法对我有效,你也可以尝试一下!顺便说一句,如果有人知道为什么splice不能与状态和索引一起使用,请告诉我,我很好奇!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接