Partage
  • Partager sur Facebook
  • Partager sur Twitter

Une boucle plutot qu'un map !!

    10 août 2020 à 22:55:55

    Bonjour

    Je suis actuellement novice en ReactJS et j'essaye de faire un projet d'étude qui consiste à reprendre des data d'une API et de les ressortir via React...
    Je  m'en sors un peu mais c'est compliqué encore pour moi à bien comprendre
     Je bute sur un souci de pouvoir mettre des conditions dans un render suite à une requete AJAX qui est en .map
    import React, {Component} from 'react'
    import Result from './Result'
    import Info from './Info'
    import {getDataArt, getDataAlb, getDataTit, getDataAll} from '../api/musicbrain'
    
    
    
    class ResultContainer extends Component{
    
        constructor(props){
            super(props);
            this.state ={
                "list" : []
            }
    
        }
    
    
        componentDidUpdate = () =>{
            if(this.props.category === "artiste"){
                getDataArt(this.props.search, this.comApi);
            }else if(this.props.category === "titre"){
                getDataTit(this.props.search, this.comApi);
            }else if(this.props.category === "album"){
                getDataAlb(this.props.search, this.comApi);
            }else{
                getDataAll(this.props.search, this.comApi);
            }
        }
    
    
        comApi = (data) =>{
            const rec = data.recordings;
            
            this.setState({
                "list" : rec
            })
        }
        
      
    
        render(){
            return(
                <div>
                    {this.state.list.map((m,i) => <Result key = {i} nombre = {i+1} artiste = {m["artist-credit"][0].name} titre = {m.title} album = {m.releases[0].title}/>)}
                </div>
            );
        }
    }
    export default ResultContainer;
    


     donc mes requetes vont bien chercher ce que je veux mais...

     
    PB numéro 1 quand je fais du console.log j'ai les résultats en boucle non stop, à cause du componentDidUpdate... Mais si je met juste componentDidMount, je n'ai aucun rendu qui s'affiche

    PB numéro 2, dans le render c'est avec le .map que j'arrive à afficher les résultats sauf quedans ce cas de figure je ne voit pas comment faire une condition, par exemple, il arrive que certains résultat n'ai pas de "releases" et dans ces cas la ça affiche une erreur et sinon pouvoir manipuler cette lignes... ou les résultats de ma requetes pour pouvoir les organiser en pagination

    Je n'ai pas partager les autres composants mais si besoin je peux le faire mais peut être certains d'entre vous trouveront la solution a mon soucis sans avouir les autres parties ^^

    Merci d'avance



    -
    Edité par d3LTa7 10 août 2020 à 22:56:58

    • Partager sur Facebook
    • Partager sur Twitter
      12 août 2020 à 13:17:27

      Bonjour,

      Pour éviter la boucle infinie au niveau du rendu, tu peux vérifier si la propriété list de ton state est déjà remplie :

      componentDidUpdate() {
        if this.state.list.length > 0 {
          return
        }
      
        const { category, search } = this.props
      
        switch(category) {
          case "artiste":
            getDataArt(search, this.comApi)
            break
          case "titre":
            getDataTit(search, this.comApi)
            break
          case "album":
            getDataAlb(search, this.comApi)
            break
          default:
            getDataAll(search, this.comApi)
        }
      }

      Mais componentDidMount() est bien la méthode qu'il est préférable d'utiliser et je ne vois aucune raison pouvant expliquer qu'elle ne fonctionne pas dans ton cas.

      Pourtant de mémoire, le componentDidUpdate() ne s'exécute pas au premier rendu (je dis bien de mémoire parce que ça fait un moment que je n'écris plus mes composants React sous forme de classe depuis que je suis passé aux hooks) donc ça ne devrait même pas fonctionner avec le componentDidUpdate().

      Ensuite dans ton render, map est une fonction qui retourne une copie du tableau d'origine en transformant chaque élément du tableau grâce à la fonction passée en paramètre.


      Le code suivant ressemblant à ce que tu as actuellement :

      this.state.list.map((m, i) => <Result key={i} prop1="value1" />)

      est équivalent à :

      this.state.list.map((m, i) => {
        return (
          <Result
            key={i}
            prop1="value1"
          />
        )
      })

      La première syntaxe est un raccourci (return implicite) de la deuxième donc en utilisant la deuxième, rien ne t'empêche de faire des conditions pour retourner ce que tu veux.

      Tu es obligé d'utiliser map pour transformer ton tableau de données en tableau de composants et retouner ce tableau pour que React insère la liste de composants dans le DOM.
      Un forEach ne fonctionnera pas car sa valeur de retour est undefined donc React n'affichera rien.

      Tu peux aussi utiliser une ternaire dans ton JSX pour gérer l'erreur sur les releases :

      render() {
        return (
          <div>
            {this.state.list.map((m, i) => (
              <Result
                key={i}
                nombre={i + 1}
                artiste={m["artist-credit"][0].name}
                titre={m.title}
                album={m.releases.length > 0 ? m.releases[0].title : null}
              />
            ))}
          </div>
        )
      }

      Sinon, tu peux directement passer ton tableau m.releases dans la prop album et gérer l'affichage dans ton composant Result.

      -
      Edité par Henskelis 12 août 2020 à 14:04:12

      • Partager sur Facebook
      • Partager sur Twitter
      Il n'y a que deux types de langages, ceux dont les développeurs se plaignent et ceux que personne n'utilise.
        14 août 2020 à 13:23:25

        Merci beaucoup pour la réponse !! Je vais voir cela de plus près :)
        • Partager sur Facebook
        • Partager sur Twitter

        Une boucle plutot qu'un map !!

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown