【问题标题】:How do I use the Array.filter() function to remove a single element from an array?如何使用 Array.filter() 函数从数组中删除单个元素?
【发布时间】:2019-09-17 01:41:52
【问题描述】:

我不确定我是否正确使用过滤器函数从数组中删除元素。我想设置它,所以当我点击元素时,它会删除元素。但是,目前它正在删除所有元素,而不仅仅是一个。元素来自点击屏幕上显示的项目(这些项目来自 API)

class App extends React.Component {
  state = {
    query: "",
    contacts: [],
    names: []
  };

  addName = (e, name) => {
    this.setState(prevState => ({
      names: [...prevState.names, name]
    }));
  };

这就是它搞砸的地方。我不知道为什么当我点击一个名字时它会删除所有的名字

  removeName = (e, name) => {
    this.setState(prevState => ({
      names: prevState.names.filter(n => n.name !== name)
    }));
  };

  onChange = e => {
    const { value } = e.target;
    this.setState({
      query: value
    });

    this.query(value);
  };

  query = query => {
    const url = ("https://jsonplaceholder.typicode.com/users");

    fetch(url)
      .then(response => response.json())
      .then(data => {
        this.setState({ contacts: data.response });
      });
  };

  componentDidMount() {
    this.query("");
  }

  render() {
    return (
      <div>
        <form>
          <input
            type="text"
            placeholder="Type names to add"
            onChange={this.onChange}
          />
          {this.state.contacts.map(contact => (
            <div key={contact.name}>
              <p>
                {contact.name}{" "}
                <button
                  onClick={e => this.addName(e, contact.name)}> Add 
                 </button>   
              </p>
            </div>
          ))}
        </form>

        {this.state.names.map(name => (
          <p key={name.name}>
            {name}{" "}
            <button
              onClick={e => this.removeName(e, name.name)}>
            </button>
          </p>
        ))}
      </div>
    );
  }
}

【问题讨论】:

  • 您是否尝试在setState 之前记录name
  • 嗯,当我使用 console.log(name) 时,它显示为未定义

标签: javascript arrays reactjs filter


【解决方案1】:

我认为发布原始答案但将其删除的人实际上有正确的想法。当您addNames 时,您正在添加字符串。名称数组由字符串组成,而不是对象。因此,当您返回 removeNames 函数时,每个元素 n 是一个字符串,n.nameundefined(即,n 是名称,n.name 什么都不是)。因此,n.name !== name 将始终为真(即,数组中的每个名称 都已定义)。您只想将nname (n !== name) 进行比较。


    removeName = (e, name) => {
        this.setState(prevState => ({
          names: prevState.names.filter(elmName => elmName !== name)
        }));
    }

在点击中:

    <button
       onClick={e => this.removeName(e, name)}>
    </button>

还有最后一件事要考虑:这只有在名称是唯一的情况下才有效。如果数组中有相同的名称,则有超过 1 个元素有被删除的风险。因此,可能需要设计一种确保唯一性的方案。即,名称 + [它在数组中的位置] 是一种快速而肮脏的方式,尽管有更好的方式。

【讨论】:

  • 我想你说的是做 prevState.bag.filter(d => d !== deviceTitle) 而不是 prevState.bag.filter(d => d.title !== deviceTitle ) 正确的?如果是这样,我试过了,它似乎没有改变任何东西,它仍然删除了所有元素
  • 甚至比这更容易(我认为)。我只是用要更新的代码块对其进行了编辑。让我知道它能让你走多远。
  • 感谢您在块中格式化!我也尝试过这种方式,当我这样做时,它不允许删除任何元素....当我以原始方式编写时,如果这就是其中的全部内容,它将删除 1 个元素,但是如果我有多个名字,它只是将它们全部删除
  • 这样做仍然会删除所有内容:/ 我也尝试了 elemName.name === name,但当我尝试删除时没有效果
  • 天哪,我发现了我的错误......当我在 onClick 中调用 removeName 时,我传入了 name.name,而它应该只是名称。现在你原来的建议有效!非常感谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-14
  • 1970-01-01
  • 1970-01-01
  • 2022-03-19
  • 1970-01-01
  • 2017-06-27
  • 1970-01-01
相关资源
最近更新 更多