Javascript-форум (https://javascript.ru/forum/)
-   Библиотеки/Тулкиты/Фреймворки (https://javascript.ru/forum/library-toolkit-framework/)
-   -   Не работает одновременно фильтр и поиск в React (https://javascript.ru/forum/library-toolkit-framework/80209-ne-rabotaet-odnovremenno-filtr-i-poisk-v-react.html)

CryNet 09.05.2020 17:30

Не работает одновременно фильтр и поиск в React
 
У меня есть компонент:

import React, {PureComponent} from 'react'

export default class Shop extends PureComponent {
  state = {
    search: "",
    filters: [],
    items: json
  };

  // проверяем какие фильтры выбрал юзер
  onFilterChange = ( event ) => {
    const checkboxes = [...event.currentTarget.closest(".filter").getElementsByTagName("input")]
    const filters = [];
    checkboxes.map(checkbox => {
      if (checkbox.checked) {
        filters.push(checkbox.name);
      }
    });
    this.setState({ filters }, this.filtredInput);
  }

  // фильтруем согласно выбранным фильтрам
  filtredInput() {
    let items = json

    if (this.state.search.length !== 0) {
      items = items.filter(word =>
        word.name.toLocaleLowerCase().indexOf(this.state.search.toLocaleLowerCase()) !== -1
      )
    }

    if (this.state.filters.length !== 0) {
      items = items.filter(element => this.state.filters.every(key => element[key]));
    }

    this.setState( {items} )
  }

  // смотрим, что вводит юзер
  onSearchChange = ( {currentTarget} ) => {
    const search = currentTarget.value
    this.setState({ search }, this.filtredInput() )
  }

  render() {
    return (
      <div>
        <div className="navigation">
          <Filter
            onFilterChange={this.onFilterChange}
          />
          <Search
            onSearchChange={this.onSearchChange}
          />
        </div>
        <Filtered
              items={this.state.items}
              updateShoppingBasket={this.updateShoppingBasket}
            />
      </div>
    )
  }
}


Помогите организовать логику так, чтобы одновременно работал и поиск, и фильтр. По отдельности всё работает отлично. Но в текущем варианте поиск работает как бы с задержкой (видимо код отрабатывает до установки стейта), но я не уверен в том, что нет других ошибок. Как правильно организовать логику фильтра + поиска?

CryNet 09.05.2020 18:56

Дополню ответ...

Если изменить функцию:

filtredInput() {
    let items = json

    setTimeout(() => {

      if (this.state.search.length !== 0) {
        items = items.filter(word =>
          word.name.toLocaleLowerCase().indexOf(this.state.search.toLocaleLowerCase()) !== -1
        )
      }

      if (this.state.filters.length !== 0) {
        items = items.filter(element => this.state.filters.every(key => element[key]));
      }

      this.setState( {items} )
    }, 1000);

  }


То всё работает как нужно, только с задержкой. Дело таки в том, что функция выполняется до установки стейта. Пока нет идей как это пофиксить.


Часовой пояс GMT +3, время: 05:12.