Реагирование: мерцание пользовательского интерфейса при обновлении состояния - PullRequest
4 голосов
/ 07 марта 2019

У меня есть компонент, который отображает данные поиска, возвращаемые из Spotify API. Однако каждый раз, когда я обновляю состояние, пользовательский интерфейс мигает:

enter image description here Входной сигнал:

            <DebounceInput
                debounceTimeout={300}
                onChange={handleChange}
            />

Крюк:

const [searchResults, setSearchResults] = useState(null)

вызов API с Apollo:

 const searchSpotify = async (query) => {
    const result = await props.client.query({
        query: SearchTracks,
        variables: {
            query
        }
    })
    const tracks = result.data.searchedTracks
    setSearchResults(tracks)
}

Рендер:

        {searchResults &&
            <div className="search-results">
                    {searchResults.map((song) => (
                            <SongInfo key={song.id} {...song} />
                    ))}
            </div>
        }

Я заметил, что это происходит только при первой загрузке. Например, если бы я должен был снова ввести запрос, он отображается без мерцания. Есть ли лучший способ реализовать это, чтобы пользовательский интерфейс не мерцал?

Ответы [ 2 ]

1 голос
/ 07 марта 2019

Ниже приведены кадры, которые вызывают мерцание. Я думаю, что происходит, что для загрузки изображений требуется некоторое время. Во время загрузки предметы имеют уменьшенную высоту. Вы должны убедиться, что макет SongInfo не зависит от того, было ли загружено изображение или нет.

Изображения не загружены - элементы свернуты:

enter image description here

Загружены изображения:

enter image description here

1 голос
/ 07 марта 2019

Я думаю, что происходит то, что вы выполняете поисковый запрос для каждого нажатия клавиши, что вызывает странное поведение.

Используйте отладку lodash, чтобы избежать поиска при каждом нажатии клавиши.Это должно устранить мерцание.(Также поможет добавление состояния загрузки)

Образец компонента debounce

import React, {Component} from 'react'
import { debounce } from 'lodash'

class TableSearch extends Component {

  //********************************************/

  constructor(props){
    super(props)

    this.state = {
        value: props.value
    }

    this.changeSearch = debounce(this.props.changeSearch, 250)
  }

  //********************************************/

  handleChange = (e) => {
    const val = e.target.value

    this.setState({ value: val }, () => {
      this.changeSearch(val)
    })
  }

  //********************************************/

  render() {

    return (
        <input
            onChange = {this.handleChange}
            value = {this.props.value}
        />
    )
  }

  //********************************************/

}
...