Partage
  • Partager sur Facebook
  • Partager sur Twitter

React Typescript usestate & class variable

Sujet résolu
    9 mai 2022 à 18:19:05

    Bonjour,

    J'ai encapsulé des variable dans une classe :

    export default class ModelUserInfo {
      name:string
      sex:string
    }


    et dans cette classe j'ai mis une fonction populate :

    populate(json){
      this.name = json.name
      this.sex = json.sex
    }


    puis dans mon component je fais :

        let [userInfo, setUserInfo] = useState(new ModelUserInfo({}))


    puis :

        useEffect( ()=>{
            fetch(endpoint)
            .then( (res) => {
                if(!res.ok) throw new Error("Error")
                return res.json()
            })
            .then( (json) => {
                userInfo.populate( json )
                setUserInfo(userInfo)
            })
        } )

    Comme vous voyez j'ai essayé de bidouiller pour que ca fonctionne dans le dernier then. Mais non ca ne fonctionne pas. Il ni a pas de "rerender" après l'utilisation de ma function populate.

    Y a t-il une solution ?

    -
    Edité par AdrienChsn 10 mai 2022 à 1:14:09

    • Partager sur Facebook
    • Partager sur Twitter
      10 mai 2022 à 0:22:11

      Bonjour, je crois que ton composant ne ce met pas à jour car tu passes la valeur actuel dans le setUserInfo.

      A noter que tu n'as pas définit la liste des dépendances dans le useEffect, donc lorsque le composant se met à jour la requête réseaux sera renvoyer.

      Un useEffect qui n'a aucune dépendance de déclaré se ré exécute à chaque fois que le composant est mis à jour.

      Si ton useEffect n'a aucune dépendance  tu dois lui passer un tabeau vide pour l'indiquer

      Voir React.js hooks useEffect

      useEffect(() => {
      
          fetch(endpoint)
          .then( (res) => {
              if(!res.ok) throw new Error("Error")
              return res.json()
          })
          .then((json) => {
              userInfo.populate( json )
              setUserInfo(userInfo)
          })
      
      }, []);

      Pour en revenir à ton problème principal, lorsque tu modifie l'état local d'un composant en utilisant le hook useState,

      en interne React avant de mettre à jour le composant vérifie si la nouvelle valeur est différente de l'ancienne valeur et si la nouvelle valeur n'est pas différente React annule la mise à jour du composant.

      La plupart du temps c'est pratique cela évite des "mise à jour superflux" des composant,

      par contre React compare les valeur avec un simple test d'égalité.

      Dans ton cas tu as une instance de class ranger dans ton state, et quand tu fait:

      setUserInfo(userInfo)

      Tu demandes à modifier l'état local avec la même instance de class

      quand React va comparer les valeurs (l'ancienne et la nouvelle) elle seront identique (même avec un simple test d'égaliter)

      car un test d'égalité sur des objet va venir comparer leurs références (à l'instar de leur valeurs).

      Une des façon de régler le problème pourrait être de ré instancier ton model au moment où tu récupères tes données,

       avec une truc du genre:

      const newUserInfo = new ModelUserInfo();
      newUserInfo.populate(json);
      
      // modifie l'état local avec une nouvelle instance
      // pour que la valeur soit détecter comme différente par React et qu'il n'annule pas le rendu
      setUserInfo(newUserInfo);

      Ce qui donne une approche un peut bizzare.

      Une autre solution qui me semble plus naturel serait de stocker uniquement le JSON dans l'état local est pas l'instance du model en entier,

      puis d'instancier le model en prenant les valeur dans l'état local:

      // stock uniquement le JSON du model dans l'état local
      let [userInfo, setUserInfo] = useState({})
      
      
      const userModel = new ModelUserInfo();
      userModel.hydrate(userInfo);
      

      Comme le composant sera recharger à chaque changement de userInfo ton userModel sera ré instancier et ré hydrater automatiquement.

      Ce qui te permet de modifier ton état local d'une façon plus naturelle:

      useEffect(() => {
      
          fetch(endpoint)
          .then( (res) => {
              if(!res.ok) throw new Error("Error")
              return res.json()
          })
          .then((json) => {
          
              setUserInfo(json);
          })
      
      }, []);






      -
      Edité par SamuelGaborieau3 10 mai 2022 à 0:23:55

      • Partager sur Facebook
      • Partager sur Twitter

      suggestion de présentation.

        10 mai 2022 à 1:23:42

        Très intéressant.

        Merci pour cette réponse :)

        • Partager sur Facebook
        • Partager sur Twitter
          11 mai 2022 à 16:44:12

          Salut que fait la methode hydrate ?

          userModel.hydrate(userInfo);



          • Partager sur Facebook
          • Partager sur Twitter

          La meilleure solution est toujours la plus simple. Ma chaîne Youtube [Tutos pour débutants]

            11 mai 2022 à 21:52:45

            @NadfriJS Bonjour, effectivement en reprenant le code de @AdrienChsn j'ai confondu le nom de la méthode populate que j'ai appelé hydrate.

            Erreur de ma part.

            • Partager sur Facebook
            • Partager sur Twitter

            suggestion de présentation.

              12 mai 2022 à 9:43:24

              Autant pour moi, je me disais que je ne connaissais pas cette methode React, et que c'etait peut-etre une nouveauté de la v18 ;)
              • Partager sur Facebook
              • Partager sur Twitter

              La meilleure solution est toujours la plus simple. Ma chaîne Youtube [Tutos pour débutants]

              React Typescript usestate & class variable

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              • Editeur
              • Markdown