J'ai une application où je dois définir la hauteur d'un élément (disons "contenu de l'application") dynamiquement. Il prend la hauteur du «chrome» de l'application et la soustrait, puis définit la hauteur du «contenu de l'application» pour s'adapter à 100% à ces contraintes. C'est super simple avec les vues vanilla JS, jQuery ou Backbone, mais j'ai du mal à comprendre quel serait le bon processus pour le faire dans React?
Voici un exemple de composant. Je veux pouvoir définir app-content
la hauteur de 100% de la fenêtre moins la taille de ActionBar
et BalanceBar
, mais comment savoir quand tout est rendu et où dois-je placer les éléments de calcul dans cette classe React?
/** @jsx React.DOM */
var List = require('../list');
var ActionBar = require('../action-bar');
var BalanceBar = require('../balance-bar');
var Sidebar = require('../sidebar');
var AppBase = React.createClass({
render: function () {
return (
<div className="wrapper">
<Sidebar />
<div className="inner-wrapper">
<ActionBar title="Title Here" />
<BalanceBar balance={balance} />
<div className="app-content">
<List items={items} />
</div>
</div>
</div>
);
}
});
module.exports = AppBase;
javascript
reactjs
Oscar Godson
la source
la source
Réponses:
componentDidMount ()
Cette méthode est appelée une fois après le rendu de votre composant. Votre code ressemblerait donc à cela.
la source
componentDidUpdate
si les valeurs peuvent changer après le premier rendu.componentDidMount()
ne provoque pas de transition.componentDidMount: () => { setTimeout(addClassFunction())}
- dire , ou utilisez rAF, la réponse ci-dessous fournit cette réponse.Un inconvénient de l'utilisation
componentDidUpdate
, oucomponentDidMount
est qu'ils sont réellement exécutés avant que les éléments dom ne soient dessinés, mais après qu'ils ont été passés de React au DOM du navigateur.Par exemple, si vous avez besoin de définir node.scrollHeight sur le node.scrollTop rendu, les éléments DOM de React peuvent ne pas suffire. Vous devez attendre que les éléments soient peints pour obtenir leur hauteur.
Solution:
Utilisez
requestAnimationFrame
pour vous assurer que votre code est exécuté après la peinture de votre nouvel objet rendula source
_this.getDOMNode is not a function
qu'est-ce que c'est que ce code?D'après mon expérience
window.requestAnimationFrame
, cela ne suffisait pas à garantir que le DOM avait été entièrement rendu / refondu à partir decomponentDidMount
. J'ai du code en cours d'exécution qui accède au DOM immédiatement après uncomponentDidMount
appel et l'utilisation uniquementwindow.requestAnimationFrame
entraînerait la présence de l'élément dans le DOM; cependant, les mises à jour des dimensions de l'élément ne sont pas encore reflétées car aucune refusion n'a encore eu lieu.Le seul moyen vraiment fiable pour que cela fonctionne était d'encapsuler ma méthode dans a
setTimeout
et awindow.requestAnimationFrame
pour s'assurer que la pile d'appels actuelle de React est effacée avant de s'inscrire pour le rendu de la prochaine image.Si je devais spéculer sur la raison pour laquelle cela se produisait / était nécessaire, je pourrais voir React regrouper les mises à jour du DOM et n'appliquer les modifications au DOM qu'après la fin de la pile actuelle.
En fin de compte, si vous utilisez des mesures DOM dans le code que vous tirez après les rappels React, vous voudrez probablement utiliser cette méthode.
la source
Juste pour mettre à jour un peu cette question avec les nouvelles méthodes de hook, vous pouvez simplement utiliser le
useEffect
hook:De plus, si vous souhaitez exécuter avant la peinture de mise en page, utilisez le
useLayoutEffect
crochet:la source
Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.
je vais l'éditer.Vous pouvez modifier l'état, puis effectuer vos calculs dans le rappel setState . Selon la documentation de React, cela est "garanti de se déclencher après l'application de la mise à jour".
Cela devrait être fait dans
componentDidMount
ou ailleurs dans le code (comme sur un gestionnaire d'événement de redimensionnement) plutôt que dans le constructeur.Ceci est une bonne alternative à
window.requestAnimationFrame
et il n'a pas les problèmes que certains utilisateurs ont mentionnés ici (devant le combiner avecsetTimeout
ou l'appeler plusieurs fois). Par exemple:la source
Je pense que cette solution est sale, mais c'est parti:
Maintenant, je vais juste m'asseoir ici et attendre les votes négatifs.
la source
React a peu de méthodes de cycle de vie qui aident dans ces situations, les listes comprenant mais sans s'y limiter getInitialState, getDefaultProps, componentWillMount, componentDidMount etc.
Dans votre cas et les cas qui doivent interagir avec les éléments DOM, vous devez attendre que le dom soit prêt, alors utilisez componentDidMount comme ci-dessous:
Pour plus d'informations sur le cycle de vie de React, vous pouvez également consulter le lien ci-dessous: https://facebook.github.io/react/docs/state-and-lifecycle.html
la source
J'ai rencontré le même problème.
Dans la plupart des scénarios en utilisant le hack-ish
setTimeout(() => { }, 0)
danscomponentDidMount()
travaillé.Mais pas dans un cas particulier; et je ne voulais pas utiliser le
ReachDOM findDOMNode
depuis la documentation dit:( Paquet source: findDOMNode )
Donc, dans ce composant particulier, j'ai dû utiliser l'
componentDidUpdate()
événement, donc mon code a fini par ressembler à ceci:Et alors:
Enfin, dans mon cas, j'ai dû supprimer l'écouteur créé dans
componentDidMount
:la source
Après le rendu, vous pouvez spécifier la hauteur comme ci-dessous et spécifier la hauteur des composants de réaction correspondants.
ou vous pouvez spécifier la hauteur de chaque composant React à l'aide de sass. Spécifiez les 2 premiers composants principaux du composant React à largeur fixe, puis la hauteur du troisième composant principal Div avec Auto. Ainsi, en fonction du contenu du troisième div, la hauteur sera attribuée.
la source
J'ai en fait un problème avec un comportement similaire, je rend un élément vidéo dans un composant avec son attribut id donc quand RenderDOM.render () se termine, il charge un plugin qui a besoin de l'id pour trouver l'espace réservé et il ne le trouve pas.
Le setTimeout avec 0 ms à l'intérieur du componentDidMount () l'a corrigé :)
la source
Dans la documentation ReactDOM.render () :
la source
ReactDOM.render
, et non pour le son niveau des composantsReactElement.render
(qui est le sujet ici).Pour moi, aucune combinaison
window.requestAnimationFrame
ousetTimeout
produit des résultats cohérents. Parfois, cela fonctionnait, mais pas toujours - ou parfois il était trop tard.Je l'ai corrigé en bouclant
window.requestAnimationFrame
autant de fois que nécessaire.(Généralement 0 ou 2-3 fois)
La clé est
diff > 0
: ici, nous pouvons garantir exactement quand la page sera mise à jour.la source
J'ai eu une situation étrange lorsque j'ai besoin d'imprimer un composant réactif qui reçoit une grande quantité de données et de la peinture sur toile. J'ai essayé toutes les approches mentionnées, aucune d'entre elles n'a fonctionné de manière fiable pour moi, avec requestAnimationFrame dans setTimeout, je reçois un canevas vide dans 20% du temps, j'ai donc fait ce qui suit:
Fondamentalement, j'ai fait une chaîne de requestAnimationFrame, je ne sais pas si c'est une bonne idée ou non, mais cela fonctionne dans 100% des cas pour moi jusqu'à présent (j'utilise 30 comme valeur pour la variable n).
la source
Il existe en fait une version beaucoup plus simple et plus propre que l'utilisation du cadre d'animation de demande ou des délais d'attente. Je suis surpris que personne n'en ait parlé: le gestionnaire de charge vanilla-js. Si vous le pouvez, utilisez le composant did mount, sinon, liez simplement une fonction sur le support de chargement du composant jsx. Si vous souhaitez que la fonction exécute chaque rendu, exécutez-la également avant de vous renvoyer les résultats dans la fonction de rendu. le code ressemblerait à ceci:
}
la source
Un peu de mise à jour avec des
ES6
classes au lieu deReact.createClass
Consultez également les méthodes de cycle de vie des composants React: le cycle de vie des composants
Chaque composant a beaucoup de méthodes similaires à
componentDidMount
eg.componentWillUnmount()
- le composant est sur le point d'être supprimé du navigateur DOMla source