web-dev-qa-db-ja.com

React:状態が更新されるとUIがちらつく

Spotify APIから返された検索データを表示するコンポーネントがあります。ただし、状態を更新するたびに、UIがちらつきます。

enter image description here 入力:

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

針:

const [searchResults, setSearchResults] = useState(null)

Apolloを使用したAPI呼び出し:

 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>
        }

最初のロードでのみ発生することに気づきました。たとえば、もう一度クエリを入力すると、ちらつきなく表示されます。 UIがちらつくことがないようにこれを実装するより良い方法はありますか?

6
Travis S.

以下は、ちらつきの原因となるフレームです。何が起こっていると私が思うのは、画像をロードするのにしばらく時間がかかることです。彼らがロードしている間、アイテムは高さが低くなっています。 SongInfoレイアウトが、イメージがロードされているかどうかに依存しないことを確認する必要があります。

画像が読み込まれていません-アイテムは折りたたまれています:

enter image description here

画像が読み込まれました:

enter image description here

2
abadalyan

何が起こっているのかと思いますが、奇妙な動作を引き起こしているすべてのキーストロークで検索クエリを実行しています。

Lodashデバウンスを使用して、すべてのキーストロークで検索を実行しないようにします。これでちらつきが解消されます。 (また、読み込み状態を追加すると役立ちます)

サンプルデバウンスコンポーネント

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}
        />
    )
  }

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

}
1
varoons