ReactJS:从列表中删除没有ID的项目?

时间:2017-05-23 22:59:25

标签: javascript reactjs

我有一个问题,即使在这里查看了一些其他帖子并尝试了一些事情之后我似乎也无法破解。我正在玩React并制作一个快速的待办事项清单。很简单,因为我可以添加新名称并按照预期在页面上显示它们。我希望能够删除我选择的项目,并且我正在环顾四周,看到其他人做这样的事情来删除项目:

deleteName(id, e) {
    const { names } = this.state;

    this.setState({
        names: names.filter(name => name.id !== id)
    });
}

这对我有意义,但我没有在我的<li>项目中添加任何ID,所以我认为我可以这样做:

this.setState({
   names: names.filter(name => name !== name)
});

但这只会删除整个列表。我究竟做错了什么?我应该重新构建如何将数组添加到数组中以获取ID并检查它吗?我将在下面发布完整的组件代码。我能得到的任何帮助总是受到赞赏。谢谢你们。

class ContactListPage extends React.Component {
    constructor(props, context) {
      super(props, context);

      this.state = {
        names: []
      };

      this.addName = this.addName.bind(this);
      this.deleteName = this.deleteName.bind(this);
    }

  addName(name) {
    const { names } = this.state;

    if (name === '') {
        console.log('add a name first!')
    } else {
        this.setState({
          names: names.concat(name)
        });
    }
  }

  deleteName(id, e) {
    const { names } = this.state;

    this.setState({
        names: names.filter(name => name !== name)
    });
  }

  render() {
    const { names } = this.state;

    const named = names.map((name, i) => (
        <Card key={i} className='todo-list'>
            <CardText>
              <li>{name}    
                <FloatingActionButton className='fab-delete' mini onClick={this.deleteName}>
                           <i className="material-icons fab-icon-delete" style={{color: 'white'}}>-</i>
                        </FloatingActionButton>
              </li>
            </CardText>
        </Card>
    ));

    return (
        <div className='contact-list'>
          <div className="field-line">
            <NewName addName={this.addName} />
            <ul className='new-name'>
              {named}
            </ul>
          </div>
        </div>
    );
  }
}

3 个答案:

答案 0 :(得分:3)

您将每个名称与自身进行比较,无论其中包含哪些内容,都会产生一个空列表(除了我猜NaN?)。

names.filter(name => name !== name)

我想你想从视图中将名称传递给你的删除功能。自从我做了React之后已经有一段时间了,但你可以用JSX中的lambda做到这一点。

deleteName(nameToDelete) {
    const { names } = this.state;

    this.setState({
        names: names.filter(name => name !== nameToDelete)
    });
}

render() {
    // Simplified to focus on the onClick change
    return names.map(name => <Card>
        ...
        <FloatingActionButton onClick={(e) => this.deleteName(name)} ... />
        ...
    </Card>);
}

如果您需要担心重复的名称,那么您可以将当前索引传递给deleteName()而不是字符串本身。如果有必要,由你决定。

答案 1 :(得分:2)

很难说,但是当您回调的传递参数实际上被称为name时,您是引用id吗?

试试这个:

deleteName(name) {
    this.setState((prevState) => ({
        names: prevState.names.filter(_name => name !== _name);
    }));
}

并更改以下内容:

onClick={this.deleteName.bind(null, name)}

答案 2 :(得分:0)

在过滤器的回调中,name !== name将始终为false,因为对象与其自身相同。即name === name。因此,表达式names.filter(name => name !== name)将返回一个空数组并删除结果。您可以将onClick处理程序更改为这样的内容,以传递您的ID:onClick={(e) => this.deleteName(i, e)},然后使用names.filter((name, i) => i !== id)来删除&#39;这个名字,虽然我想你可能想要制作一个名字数组的副本,然后将相应的名字拼接出来。