React: Manipulation du DOM dans componentDidUpdate

Créé le 23 sept. 2016  ·  3Commentaires  ·  Source: facebook/react

Salut, c'est plutôt une question, j'aimerais ouvrir une discussion concernant la manipulation du DOM dans componentDidUpdate .

Je crée un plugin React. Il doit faire quelques calculs DOM, car CSS n'est pas assez puissant pour couvrir tout ce que ce plugin doit faire. Le problème est que je dois ajuster certaines propriétés CSS en fonction de la valeur de retour de getBoundingClientRect() d'un autre élément DOM rendu par le même composant .

Donc techniquement, nous avons 3 options :

1) Calculez getBoundingClientRect en componentDidUpdate et appelez setState avec les valeurs calculées. J'ai peur de la boucle infinie qui pourrait arriver dans certains cas, donc je ne choisirais pas celle-ci.

2) Faites comme en 1) et jouez un peu avec shouldComponentUpdate , mais cela semble très complexe et illisible. De nombreuses questions surgissent qui dépendent de certains cas d'utilisation.

3) Mettez à jour le DOM à partir de componentDidUpdate. C'est la solution que j'ai décidé d'opter, cela fonctionne, c'est simple, stable et fonctionne comme prévu. Cependant, je sens que je suis à la limite, alors je voulais vérifier que c'était une bonne façon de faire les choses. Est-il correct de manipuler DOM dans componentDidUpdate ? Il est appelé à chaque fois que render est fait, et je suis d'accord pour jeter mes modifications, car pour le prochain render je modifierai à nouveau le DOM.

Voici une partie du code

componentDidMount() {
  this.recalculateIndent();
}

componentDidUpdate() {
  this.recalculateIndent();
}

recalculateIndent() {
  // calculate indent based on getBoundingClientRect of some DOM reference
  this.textareaRef.style.textIndent = `${indent}px`;
}

render() {
   return (
   ...
   <textarea ref={ref => this.textareaRef = ref}/>
   ...
   );
}

Commentaire le plus utile

@jvorcak utilisant componentDidUpdate est le bon endroit pour manipuler le DOM manuellement après un rendu. Par les docs :

Profitez-en pour opérer sur le DOM lorsque le composant a été mis à jour.

De plus, nous essayons d'utiliser le suivi des problèmes uniquement pour les demandes de fonctionnalités et les rapports de bogues. Les questions d'utilisation doivent être dirigées ailleurs, comme Discuter.reactjs.org ou StackOverflow. Merci!

Tous les 3 commentaires

Chaque solution (méthode du cycle de vie des composants) est appropriée pour une situation concrète, mais la manipulation du DOM est erronée. Utiliser l'état et le composant de rendu. Exemple pour mon dernier cas d'utilisation "en-tête fixe pour le tableau + défilement virtuel pour le corps du tableau", j'espère que cela vous aidera à comprendre le flux correct.

  1. Constructeur de composant : valeur de l'état initial : bodyHeight = 0 (ou null, comme vous le souhaitez).
  2. Premier rendu, rend l'en-tête du tableau mais le corps du tableau vide (0 lignes).
  3. componentDidMount - lit la hauteur du DOM de l'en-tête et du conteneur (+ quelques calculs...) et setState pour bodyHeight (re-rendu).
  4. Deuxième rendu, bodyHeight !== 0, le corps de la table sera rendu. Maintenant, le paramètre de hauteur est connu ( je peux le définir à l'aide de l'accessoire de composant "style", plutôt que de la manipulation DOM ), je peux ajouter des composants pour les lignes.
  5. Écouteur d'événement supplémentaire pour "redimensionner" (redimensionnement du document/navigateur), ajouter dans componentDidMount, supprimer dans componentWillUnmount. Dans le gestionnaire d'événements, je fais la même chose que dans componentDidMount - lisez les nouvelles valeurs de hauteur DOM et setState.
  6. Il n'y a pas de manipulation du DOM à la main, React fait le boulot.

@jvorcak utilisant componentDidUpdate est le bon endroit pour manipuler le DOM manuellement après un rendu. Par les docs :

Profitez-en pour opérer sur le DOM lorsque le composant a été mis à jour.

De plus, nous essayons d'utiliser le suivi des problèmes uniquement pour les demandes de fonctionnalités et les rapports de bogues. Les questions d'utilisation doivent être dirigées ailleurs, comme Discuter.reactjs.org ou StackOverflow. Merci!

Que faire si vous souhaitez mettre à jour un composant après avoir modifié quelque chose dans un autre ?

Cette page vous a été utile?
0 / 5 - 0 notes