Как использовать функцию Array.filter () для удаления одного элемента из массива? - PullRequest
2 голосов
/ 28 апреля 2019

Я не уверен, правильно ли я использую функцию фильтра для удаления элемента из массива. Я хотел бы настроить его, чтобы при нажатии на элемент он удалялся. Но в настоящее время он удаляет все элементы, а не только один. Элементы появляются при нажатии на элементы, отображаемые на экране (эти элементы из 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>
    );
  }
}

1 Ответ

3 голосов
/ 28 апреля 2019

Я думаю, что человек, который разместил оригинальный ответ, но удалил его, действительно имел правильную идею.Когда вы addNames, вы добавляете строки.Массив имен состоит из строк, а не объектов.Таким образом, когда вы возвращаетесь к своей функции removeNames, каждый элемент n является строкой, а n.name является undefined (т. Е. n - это имя, n.name - ничто).Следовательно, n.name !== name всегда будет истинным (т. Е. Каждое имя в массиве определено ).Вместо этого вы хотите просто сравнить n с name (n !== name).


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

И в onclick:

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

И еще одна заключительная вещь для рассмотрения: этобудет работать только если имена являются уникальными.Если в массиве одинаковые имена, существует риск удаления более 1 элемента.Поэтому может быть желательно разработать схему обеспечения уникальности.Т.е. name + [это позиция в массиве] - быстрый и грязный способ, хотя есть и лучшие способы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...