web-dev-qa-db-fra.com

Existe-t-il un moyen de vérifier si le composant de réaction est démonté?

J'ai un cas d'utilisation où j'ai besoin de démonter mon composant de réaction. Mais dans certains cas, le composant de réaction particulier est démonté par une fonction différente . Par conséquent, je dois vérifier si le composant est monté avant de le démonter.

35
Dharini S

Puisque isMounted() est officiellement obsolète, vous pouvez le faire dans votre composant:

componentDidMount() { 
  this._ismounted = true;
}

componentWillUnmount() {
   this._ismounted = false;
}

Ce modèle de gestion de votre propre variable state est détaillé dans la documentation ReactJS: https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html

64
Shubham Khatri

Je pense que la réponse de Shubham est une solution de contournement suggérée en réagissant pour les personnes qui doivent faire la transition de leur code pour cesser d'utiliser l'anti-modèle isMounted.

Ce n’est pas nécessairement mauvais, mais cela vaut la peine d’énumérer les vraies solutions à ce problème.

L'article lié par Shubham propose 2 suggestions pour éviter cet anti motif. Celui dont vous avez besoin dépend de la raison pour laquelle vous appelez setState lorsque le composant est démonté.

si vous utilisez un magasin de flux dans votre composant, vous devez vous désabonner dans composantWillUnmount

class MyComponent extends React.Component {
  componentDidMount() {
    mydatastore.subscribe(this);
  }
  render() {
    ...
  }
  componentWillUnmount() {
    mydatastore.unsubscribe(this);
  }
}

Si vous utilisez des promesses ES6, vous devrez peut-être emballer votre promesse pour la rendre annulable.

const cancelablePromise = makeCancelable(
  new Promise(r => component.setState({...}}))
);

cancelablePromise
  .promise
  .then(() => console.log('resolved'))
  .catch((reason) => console.log('isCanceled', reason.isCanceled));

cancelablePromise.cancel(); // Cancel the promise

En savoir plus sur makeCancelable dans l'article lié.

En conclusion, n'essayez pas de corriger ce problème en définissant des variables et en vérifiant si le composant est monté, allez à la racine du problème. Veuillez commenter avec d'autres cas courants si vous pouvez en proposer un.

19
Nicola Pedretti

Une autre solution serait d’utiliser Refs . Si vous utilisez React 16.3+, créez une référence pour votre élément de niveau supérieur dans la fonction de rendu.

Ensuite, vérifiez simplement si ref.current est null ou non.

Exemple:

class MyClass extends React.Component {
  constructor(props) {
    super(props);
    this.elementRef = React.createRef();
  }

  checkIfMounted() {
     return this.elementRef.current != null;
  }

  render() {
    return (
      <div ref={this.elementRef} />
    );
  }
}
6
Tarun Gehlaut

Je suis arrivé ici parce que je cherchais un moyen d'arrêter polling l'API.

Le react docs couvre le cas websocket, mais pas le polling.

La façon dont j'ai travaillé autour 

// React component

React.createClass({
    poll () {
        if (this.unmounted) {
            return
        }
        // otherwise, call the api
    }
    componentWillUnmount () {
        this.unmounted = true
    }
})

Ça marche. J'espère que ça aide

S'il vous plaît, laissez-moi savoir si vous connaissez un cas de test ayant échoué pour ceci =]

4
melloc

La même idée mais une autre mise en œuvre

/**
 * component with async action within
 * 
 * @public
 */
class MyComponent extends Component {
    constructor ( ...args ) {
        // do not forget about super =)
        super(...args);
        // NOTE correct store "setState"
        let originSetState = this.setState.bind(this);
        // NOTE override
        this.setState = ( ...args ) => !this.isUnmounted&&originSetState(...args);
    }
    /**
     * no necessary setup flag on component mount
     * @public
     */
    componentWillUnmount() {
        // NOTE setup flag
        this.isUnmounted = true;
    }
    /**
     *
     * @public
     */
    myCustomAsyncAction () {
        // ... code
        this.setState({any: 'data'}); // do not care about component status
        // ... code
    }

    render () { /* ... */ }
}

1
Sajera Cool

Vous pouvez utiliser:

myComponent.updater.isMounted(myComponent)

"myComponent" est une instance de votre composant react . elle retournera 'true' si le composant est monté et 'false' si ce n'est pas ..

  • Ceci est non supporté moyen de le faire. vous feriez mieux de vous désabonner des événements/événements asynchrones sur composantWillUnmount .
0
Danny Michaeli