2
votes

Comment utiliser componentWillUnmount dans React Native?

  componentDidMount () {
        this.showPosts();
  }

  showPosts = async () => {

    var userID = await AsyncStorage.getItem('userID');

    fetch(strings.baseUri+"getPostWithUserID", {
        method: 'POST',
        headers: {
           Accept: 'application/json',
           'Content-Type': 'application/json'
        },
        body: JSON.stringify({ 
            "user_id": userID
        })
        })
        .then((response) => response.json())
        .then((responseJson) => {

          this.setState({show: false}); // If I comment this line, then I don't get the warning.

        })
        .catch((error) => {
            console.error(error);
        });
  }
How to use componentWillUnmount because I'm getting the warning below.
Is there a way I can setState show to true when I use componentWillUnmount?
Warning

2 commentaires

Copie possible de Comment annuler une récupération sur componentWillUnmount


@Andrew est-ce possible si vous pouviez donner une réponse dans mon scénario? Je ne suis pas en mesure de comprendre comment utiliser ce qui est indiqué dans le lien que vous avez fourni. TIA :)


4 Réponses :


0
votes

Vous pouvez vérifier si le composant est monté de cette façon, puis vérifier cette variable dans votre fonction asynchrone pour voir si vous pouvez toujours exécuter la fonction ou autrement pour l'annuler:

componentDidMount() { 
  this.mounted = true;
}

componentWillUnmount() {
  this.mounted = false;
}

async asyncFunction {
  if(this.isMounted){
    setState(....);
  }else{
    return;
  }
}


8 commentaires

la question est de savoir comment empêcher la définition de l'état en fonctionnement asynchrone si le composant est démonté - donc toujours pertinent, je dirais


@Mtg Kha Jeskai oui je le sais, est-ce que je peux quand même empêcher cet avertissement?


ici -> stackoverflow.com/ questions / 49906437 /… vous avez la possibilité de l'éviter


if (this.isMounted) doit être exactement avant setState pas avant la récupération


Cela me donne un avertissement indiquant que isMounted est obsolète.


Oh, alors isMounted est un mot réservé? Essayez avec "this.myComponentIsMounted", cela fonctionnerait probablement.


Je ne pense pas que myComponentIsMounted soit un mot réservé


C'est la raison pour laquelle je vous ai dit de l'utiliser, cela a-t-il fonctionné?



0
votes

vous pouvez utiliser une propriété d'objet de composant interne comme - isComponentMounted puis la vérifier pendant le rappel de l'opération asynchrone.


2 commentaires

Comment faire ça?


vous devrez le définir vous-même puis le contrôler avec des méthodes de cycle de vie - componentDidMount () {this.isComponentMounted = true}, componentWillUnmount () {this.isComponentMounted = false}



3
votes

Vous mélangez plusieurs éléments dans votre code. Vous utilisez await mais vous n'appelez pas await lorsque vous utilisez this.showPosts () . Vous n'emballez pas non plus votre await dans un try / catch comme await peut le lancer.

Il existe plusieurs façons de résoudre le problème de la définition de l'état d'un composant non monté. Le plus simple, bien qu'il s'agisse d'un anti-pattern, est de définir une variable dans le componentDidMount et le componentWillUnmount qui suit l'état monté du composant.

Refactorisons donc votre code pour qu'il ait plus de sens

Voici à quoi ressembleront désormais votre componentDidMount et le componentWillUnmount .

showPosts = async () => {
  try {
    var userID = await AsyncStorage.getItem('userID');

    fetch(strings.baseUri + 'getPostWithUserID', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        'user_id': userID
      })
    })
      .then((response) => response.json())
      .then((responseJson) => {
        if (this._isMounted) {
          this.setState({show: false}); // If I comment this line, then I don't get the warning.
        }
      })
      .catch((error) => {
        console.error(error);
      });
  } catch (err) {
    console.warn(err);
  }
}

Mise à jour de showPosts pour qu'il soit purement async/await

showPosts = async () => {
  try {
    var userID = await AsyncStorage.getItem('userID');
    let response = await fetch(strings.baseUri + 'getPostWithUserID', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        'user_id': userID
      })
    });

    let responseJson = await response.json();
    if (this._isMounted) {
      this.setState({show: false});
    }
  } catch (err) {
    console.error(error);
  }
}


6 commentaires

MERCI BEAUCOUP @Andrew. Cela a finalement fonctionné pour moi. Mais j'ai une question, pourquoi avons-nous créé la variable en utilisant this._isMounted . Je veux dire, pouvez-vous s'il vous plaît me dire où il est écrit que vous créez une variable de cette façon.


De plus, je viens de vérifier que isMounted avant d'appeler setState () élimine l'avertissement . Alors la solution que vous m'avez donnée, est-ce la bonne façon ou un hack?


this.isMounted () est obsolète et sera supprimé ultérieurement. Il est préférable de ne pas utiliser de fonctions obsolètes.


non je veux dire la solution globale est-ce la bonne façon? Parce que l'article dit que if (this.isMounted ()) {this.setState ({})} cela élimine l'avertissement


Oui, c'est une solution valable. L'article dit: Une stratégie de migration simple pour quiconque met à niveau son code pour éviter isMounted () consiste à suivre le statut monté vous-même. Définissez simplement une propriété _isMounted sur true dans componentDidMount et définissez-la sur false dans componentWillUnmount, et utilisez cette variable pour vérifier l'état de votre composant. Donc, ce que nous avons fait est évité d'utiliser une API obsolète et utilisé une solution qui fonctionne.


@ShubhamBisht Je n'utilise pas react-native-video



0
votes

Ce n'est pas une bonne idée de définir l'état dans componentDidMount sans état initial dans le constructeur car cela déclenche un rendu supplémentaire, ce qui peut entraîner des problèmes de performances.

De la documentation officielle:

Vous pouvez appeler setState () immédiatement dans componentDidMount (). Cela déclenchera un rendu supplémentaire, mais cela se produira avant que le navigateur ne mette à jour l'écran. Cela garantit que même si le render () sera appelé deux fois dans ce cas, l'utilisateur ne verra pas l'état intermédiaire. Utilisez ce modèle avec prudence car il entraîne souvent des problèmes de performances. Dans la plupart des cas, vous devriez pouvoir affecter l'état initial dans le constructeur () à la place. Cela peut cependant être nécessaire dans des cas comme les modaux et les info-bulles lorsque vous devez mesurer un nœud DOM avant de rendre quelque chose qui dépend de sa taille ou de sa position.

https://reactjs.org/docs/react-component.html#componentdidmount

Mais cela nous ramène à POURQUOI vous voudriez utiliser componentWillUnmount? C'est pour les événements de désinscription, les notifications push, le nettoyage des ressources.


0 commentaires