web-dev-qa-db-fra.com

React: UI scintille lorsque l'état est mis à jour

J'ai un composant qui affiche les données de recherche renvoyées par l'API Spotify. Cependant, chaque fois que je mets à jour l'état de l'interface utilisateur scintille:

enter image description here Entrée:

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

Crochet:

const [searchResults, setSearchResults] = useState(null)

Appel API avec Apollo:

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

Rendre:

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

J'ai remarqué que cela ne se produit que lors du premier chargement. Par exemple, si je devais taper à nouveau la requête, elle s'affiche sans scintillement. Existe-t-il une meilleure façon de mettre en œuvre cela afin que l'interface utilisateur ne scintille pas?

6
Travis S.

Voici les cadres qui provoquent le scintillement. Je pense que cela prend du temps pour que les images se chargent. Pendant le chargement, les objets ont une hauteur réduite. Vous devez vous assurer que la mise en page SongInfo ne dépend pas du chargement ou non de l'image.

Images non chargées - les éléments sont réduits:

enter image description here

Les images ont été chargées:

enter image description here

2
abadalyan

Je pense que ce qui se passe, c'est que vous exécutez une requête de recherche à chaque coup de clé qui provoque le comportement étrange.

Utilisez la fonction anti-rebond de lodash pour éviter de faire une recherche à chaque coup de touche. Cela devrait répondre au scintillement. (De plus, l'ajout d'un état de chargement aidera)

Exemple de composant anti-rebond

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