web-dev-qa-db-fra.com

Rendu composant après réponse api

J'ai un composant de réaction que je souhaite remplir avec des images à l'aide de l'API Dropbox. La partie api fonctionne bien, mais le composant est rendu avant que les données ne passent et que le tableau soit vide. Comment puis-je retarder le rendu du composant jusqu'à ce qu'il dispose des données nécessaires?

var fileList = [];
var images = [];
var imageSource = [];

class Foo extends React.Component {

 render(){
  dbx.filesListFolder({path: ''})
  .then(function(response) {
   fileList=response.entries;
   for(var i=0; i<fileList.length; i++){
    imageSource.Push(fileList[0].path_lower);
   }
   console.log(imageSource);
   })

  for(var a=0; a<imageSource.length; a++){
   images.Push(<img key={a} className='images'/>);
  }

  return (
   <div className="folioWrapper">
    {images}
   </div>
  );
 }
}

Merci de votre aide!

7
r_cahill

Changements:

1. Ne faites pas l'appel api dans la méthode de rendu, utilisez la méthode componentDidMount lifecycle pour cela.

composantDidMount:

composantDidMount () est invoqué immédiatement après qu'un composant est monté. L'initialisation nécessitant des noeuds DOM devrait aller ici. Si vous besoin de charger des données à partir d’un terminal distant, c’est un bon endroit pour instancier la requête réseau. Le réglage de l’état dans cette méthode entraînera déclencher un re-rendu.

2. Définissez la variable imageSource dans le tableau d'état avec la valeur initiale []. Une fois que vous aurez obtenu la mise à jour de la réponse à l'aide de setState, le composant sera automatiquement rendu avec les données mises à jour.

3. Utilisez le tableau d'état pour générer les composants ui dans la méthode de rendu.

4. Pour conserver le rendu jusqu'à ce que vous n'ayez pas obtenu les données, placez la condition dans la méthode render, vérifiez la longueur du tableau imageSource si longueur est égal à zéro, puis return null.

Écris-le comme ceci:

class Foo extends React.Component {

    constructor(){
        super();
        this.state = {
            imageSource: []
        }
    }

    componentDidMount(){
        dbx.filesListFolder({path: ''})
          .then((response) => {
              let fileList = response.entries;
              this.setState({
                  imageSource: fileList
              });
          })
    }

    render(){
        if(!this.state.imageSource.length)
            return null;

        let images = this.state.imageSource.map((el, i) => (
            <img key={i} className='images' src={el.path_lower} />
        ))

        return (
            <div className="folioWrapper">
                {images}
            </div>
        );
    }
}
8
Mayank Shukla

Vous devriez utiliser l'état ou les accessoires de votre composant pour qu'il soit rendu à nouveau lors de la mise à jour des données. L'appel à Dropbox doit être effectué en dehors de la méthode render sinon vous utiliserez l'API chaque fois que le composant effectuera un nouveau rendu. Voici un exemple de ce que vous pourriez faire.

class Foo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      imageSource: []
    }
  }

  componentDidMount() {
    dbx.filesListFolder({ path: '' }).then(function(response) {
      const fileList = response.entries;

      this.setState({
        imageSource: fileList.map(file => file.path_lower);
      })
    });
  }

  render() {
    return (
      <div className="folioWrapper">
        {this.state.imageSource.map((image, i) => <img key={i} className="images" src={image} />)}
      </div>
    );
  }
}

S'il n'y a pas encore d'images, il restera simplement à rendre une div vide de cette façon.

5
DonovanM

Tout d'abord, vous devez utiliser l'état état du composant et non des variables définies globalement.

Ainsi, pour éviter d'afficher le composant avec un tableau d'images vide, vous devez appliquer une classe de "chargement" conditionnelle sur le composant et la supprimer lorsque le tableau n'est plus vide.

0
Francisco Mateo