Pourquoi array.length est-il égal à 0 lorsqu'il n'est pas vide, et comment puis-je le parcourir en boucle ?


Jaeger

Je suis un peu confus, cela devrait être assez évident mais je me perds en essayant de tout comprendre.

Je crée un formulaire avec React, et l'utilisateur peut sélectionner quelques images. Mon objectif initial est d'afficher l'aperçu, mais pour une raison que je ne comprends pas, je ne peux pas mapper le tableau des résultats même si je peux voir avec un console.log()qu'il n'est pas vide

Voici comment je crée le tableau :

constructor(props) {
    super(props);
    this.state = {
        // Some other elements
        m_filename: [],
    };
}

handleMultiUpload() {

    let files = document.getElementById('multiple_files_upload');
    let files_result = [];

    for(let i = 0; i < files.files.length; i++) {
        let reader = new FileReader();
        reader.readAsDataURL(files.files[i]);
        reader.onloadend = function() {
            // console.log(reader.result);
            files_result.push({
                "id": i,
                "name": files.files[i].name,
                "img": reader.result
            });
        }
    }

    this.setState({
        m_file: files_result,
    });
}

render() {

    const { m_file } = this.state;

    // rest of my code
}

À partir de là, lorsque j'utilise console.logla m_filevariable, elle renvoie quelque chose ressemblant à ceci :

[
  0:
    id: 0
    name: "file.jpg"
    img: "[base64 file rendered here]"
  1:
    id: 1
    name: "cat.jpg"
    img: "[base64 file rendered here]"
  ...etc
] 

J'essaie de boucler m_fileen procédant comme suit :

{
  m_file !== null && m_file.map(function(tile) {
      return (
          <li key={tile.id}>
              <img src={tile.img}/>
          </li>
      )
}

Les problèmes sont multiples :

  • m_file.length renvoie 0
  • En conséquence je n'arrive pas à le parcourir en boucle et à afficher mes images
  • Même si console.log() les affiche sous forme de tableau, lorsque I console.log(typeof m_file), il renvoie un objet. Je suppose que c'est un stateobjet, mais... comment puis-je le gérer, alors que je n'ai aucun problème à mapper via json ailleurs?

J'ai l'impression d'ignorer une évidence.

Merci d'avance

Belmin Bedak

Depuis MDN :

L'objet FileReader permet aux applications Web de lire de manière asynchrone le contenu des fichiers (ou des tampons de données brutes) stockés sur l'ordinateur de l'utilisateur, en utilisant des objets File ou Blob pour spécifier le fichier ou les données à lire.

Étant donné que le traitement FileReaderest asynchrone, lorsque vous setState, votre variable file_resultest toujours un tableau vide.

L'une des solutions possibles est d'appeler la fonction à l' setStateintérieur reader.onloadend, juste après avoir poussé les éléments vers le tableau

let self = this;
reader.onloadend = function() {
   // console.log(reader.result);
   files_result.push({
      "id": i,
      "name": files.files[i].name,
      "img": reader.result
   });
   self.setState({
       m_file: files_result,
   });   
}

Remarque : le thismot-clé serait lié à l' FileReaderobjet, la référence correcte doit donc être conservée dans la variable.

Voici la belle explication des trucs Async en Javascript - https://stackoverflow.com/a/4560233/3918577

Articles connexes