@bobrui4anin

Как удалить отфильтрованный элемента массива?

Уважаемые друзья, недавно начал разбираться с React'om. И делая очередной мини таск, столкнулся с такой проблемой. Вот исходник:
var debtorsArr = {items: ['Волков А.В. - Фленов "Р.А.Б."','Фисюк А.Г. - Лилиан "Я читаю Ваши мысли"','Малинов В.И. - Писарев "Экономика"','Павловский Е.А. - Ширшнев "Эта интересная история"']};

        class MainVue extends React.Component {
            constructor(props) {
                super(props);
                this.state = {items: this.props.arr.items, value: '', clear: ''};
            }
            deleteItem(index) {
                this.props.arr.items.splice(index, 1);
                this.setState({items: this.props.arr.items});
            }
            addItem() {
                this.props.arr.items.push(this.state.value);
                this.setState({items: this.props.arr.items, value: this.state.clear});
            }
            handleChange(event) {
                this.setState({value: event.target.value});
            }
            findItems(event) {
                // console.log('this.props.arr.items', this.props.arr.items);
                var filterList = this.props.arr.items.filter((item) => {
                // console.log('status', item.toLowerCase().search(event.target.value.toLowerCase()) !== -1);
                return item.toLowerCase().search(event.target.value.toLowerCase()) !== -1;
                });
                // console.log('items', filterList);
                this.setState({items: filterList});
            }
            render() {
                var showItems = this.state.items.map((item, index) => {
                    return <li key={index}>{item} <button onClick={this.deleteItem.bind(this, index)}>Удалить</button></li>
                });
                return <div>
                    <div>
                        <input value={this.state.value} onChange={this.handleChange.bind(this)} placeholder="Add debtor..."/>
                        <button onClick={this.addItem.bind(this)}>Добавить</button>
                    </div>
                    <div>
                        <input onChange={this.findItems.bind(this)} placeholder="Search debtor..."/>
                    </div>
                    <ul>
                        {showItems}
                    </ul>
                </div>
            }
        }

        ReactDOM.render(
            <MainVue arr={debtorsArr}/>,
            document.getElementById('app')
        );

1-ый инпут для добавления элемента в массив, 2-ой инпут для фильтрации. Когда мы начинаем работать с отфильтрованным элементом - он представляет из себя li>...button>удалить, собственно в чем вся загвоздка - по нажатию на кнопку "удалить" удаляется 0 элемент массива, но не отфильтрованный, подскажите, где я что то упустил. Буду рад любому ответу !!!
  • Вопрос задан
  • 234 просмотра
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
Косяк в том, что передаёте в deleteItem индекс элемента отфильтрованного массива, а удаляете из исходного.

Давайте вместо индексов будем использовать уникальные id (вместо строк в items придётся хранить объекты):

deleteItem(id) {
  this.setState(({ items }) => ({
    items: items.filter(n => n.id !== id),
  }));
}

Полный код
class App extends React.Component {
  state = {
    items: [...this.props.items.map((n, i) => ({
      id: i + 1,
      value: n,
    }))],
    newItem: '',
    search: '',
  }

  addItem = () => {
    this.setState(({ items, newItem }) => ({
      items: [ ...items, {
        id: 1 + Math.max(0, ...items.map(n => n.id)),
        value: newItem,
      } ],
      newItem: '',
    }));
  }

  deleteItem(id) {
    this.setState(({ items }) => ({
      items: items.filter(n => n.id !== id),
    }));
  }

  onChange = ({ target: { value, name } }) => {
    this.setState(() => ({
      [name]: value,
    }));
  }

  render() {
    const search = this.state.search.toLowerCase();
    const filteredItems = this.state.items.filter(n => n.value.toLowerCase().includes(search));

    return (
      <div>
        <div>
          <input
            value={this.state.newItem}
            onChange={this.onChange}
            name="newItem"
            placeholder="Add..."
          />
          <button onClick={this.addItem}>Добавить</button>
        </div>
        <div>
          <input
            value={this.state.search}
            onChange={this.onChange}
            name="search"
            placeholder="Search..."
          />
        </div>
        <ul>
          {filteredItems.map(n => (
            <li key={n.id}>
              {n.value}
              <button onClick={() => this.deleteItem(n.id)}>Удалить</button>
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

ReactDOM.render(
  <App
    items={[
      'hello, world!!',
      'fuck the world',
      'fuck everything',
    ]}
  />,
  document.getElementById('app')
);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы