Панель поиска для фильтрации результатов таблицы в Реакция с тайм-аутом - PullRequest
0 голосов
/ 30 августа 2018

Я использую пользовательский интерфейс Semantic React Поиск для фильтрации результатов компонента таблицы данных в React. Таблица должна отображать все данные, если поиск пуст, и не отображать данные или соответствующие результаты, если поиск не пуст. Моя проблема в том, что во время поиска всегда появляется быстрое сообщение «Нет данных».

Исходный код поиска отображал результаты в виде раскрывающегося списка, но я изменил его, чтобы изменить таблицу. Код ниже.

class Page extends Component {
  resetComponent = () => this.setState({ isLoading: false, results: [], value: '' })

  handleSearchChange = (e, { value }) => {
    this.setState({ isLoading: true, value })

    setTimeout(() => {
      if (this.state.value.length < 1) return this.resetComponent()

      const re = new RegExp(_.escapeRegExp(this.state.value), 'i')
      const isMatch = result => re.test(result.name)

      this.setState({
        isLoading: false,
        results: _.filter(this.props.users, isMatch),
      })
    }, 200)
  }

  render() {
    const { users } = this.props
    const { value, results } = this.state
    const dataToShow = _.isEmpty(results) && !value ? users : results

    return (
      <Container>
        <Search
          open={false}
          loading={isLoading}
          onSearchChange={_.debounce(this.handleSearchChange, 500, { leading: true })}
          value={value}
          {...this.props}
        />
        <Table data={dataToShow} />
      </Container>
    )
  }
}

Я думаю, что строка const dataToShow = _.isEmpty(results) && !value ? users : results заставляет его мигать, но я не знаю, как еще не отображать результаты, если нет совпадений, или все результаты, если они пусты.

Как мне заставить этот тайм-аут / отладку правильно работать на столе?

Если я сделаю <Table data={results} />, отладка работает, но таблица не отображает все данные при начальной загрузке.

1 Ответ

0 голосов
/ 30 августа 2018

На самом деле происходит, когда вы устанавливаете this.setState({ isLoading: true, value }), компонент будет повторно визуализироваться, так как вы изменили состояние. Когда это происходит, эта строка:

const dataToShow = _.isEmpty(results) && !value ? users : results

на самом деле покажет results - так как, хотя результаты пусты, вы набираете значение. Вот почему вы получаете «Нет данных», так как привязываете к результатам, но они пусты.

Попробуйте это там:

const dataToShow = _.isEmpty(results) && !value ? users : this.state.isLoading ? users : results

Он должен продолжать показывать users, когда введено значение и после того, как вы закончите загрузку, оно должно измениться на результаты.

Однако проблема заключается в том (именно поэтому я предложил простой выход с вращателем), что теперь вы будете показывать результаты ... затем при новом поиске вы вернетесь к пользователям, а затем снова вернетесь к результатам после завершения загрузки. .

Я бы вообще не отображал <Table>, в то время как this.state.isLoading имеет значение true, и отображал бы некоторый «счетчик», если он есть ... например:

    class Page extends Component {
      resetComponent = () => this.setState({ isLoading: false, results: [], value: '' })
    
      handleSearchChange = (e, { value }) => {
        setTimeout(() => {
           this.setState({ isLoading: true, value })

           if (this.state.value.length < 1) return this.resetComponent()
           const re = new RegExp(_.escapeRegExp(this.state.value), 'i')
           const isMatch = result => re.test(result.name)
           this.setState({
              isLoading: false,
              results: _.filter(this.props.users, isMatch),
           })
        }, 200)
	  }

      render() {
        const { users } = this.props
        const { value, results } = this.state
        const dataToShow = _.isEmpty(results) && !value ? users : results
    
        return (
          <Container>
            <Search
              open={false}
              loading={isLoading}
              onSearchChange={_.debounce(this.handleSearchChange, 500, { leading: true })}
              value={value}
              {...this.props}
            />
            {this.state.isLoading && <Spinner />}
            {!this.state.isLoading && <Table data={dataToShow} />}
          </Container>
        )
      }
    }

Но поскольку мы не согласны с этим шаблоном UX, вот еще одно предложение:

Отслеживайте предыдущие результаты и продолжайте показывать их, пока новое изменение состояния не произойдет с новыми результатами:

class Page extends Component {
  constructor (props) {
     super(props)
     this.state = {
        isLoading: false,
        results: [],
        oldResults: this.prop.users || [],
        value: ''
     }
   }
	
  resetComponent = () => this.setState({ isLoading: false, results: [], oldResults: this.prop.users || [], value: '' })

  handleSearchChange = (e, { value }) => {
    setTimeout(() => {
    this.setState({ isLoading: true, value })

    if (this.state.value.length < 1) return this.resetComponent()
			 
    const re = new RegExp(_.escapeRegExp(this.state.value), 'i')
    const filteredResults = _.filter(this.props.users, result => re.test(result.name))
       this.setState({
         isLoading: false,
         results: filteredResults,
         oldResults: filteredResults
       })
    }, 200)
  }

  render() {
    const { users } = this.props
    const { value, results } = this.state
    const dataToShow = (_.isEmpty(results) && !value) || this.state.isLoading ? oldResults : results
    return (
      <Container>
        <Search
          open={false}
          loading={isLoading}
          onSearchChange={_.debounce(this.handleSearchChange, 500, { leading: true })}
          value={value}
          {...this.props}
        />
	<Table data={dataToShow} />
      </Container>
    )
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...