J'essaie d'animer la hauteur des éléments avec ReactCSSTransitionGroup
, voici donc à quoi je voudrais que l'animation ressemble:
http://jsfiddle.net/cherrry/hgk4Lme9/
Le problème est que je ne connais pas toujours la hauteur de l'élément, j'ai donc essayé de pirater les scrollHeight
, clientHeight
ou quelque chose de similaire pendant componentDidMount
et d'essayer de définir node.style.height
ou ajouter des règles à la feuille de style
http://jsfiddle.net/cherrry/dz8uod7u/
Quitter l'animation semble bon, mais lorsque l'élément entre, il clignote un peu et l'animation de mise à l'échelle semble étrange
Cela devrait être dû à la demande de node.scrollHeight
a provoqué le rendu immédiatement, est-il donc possible d'obtenir les mêmes informations et d'injecter des règles CSS avant le démarrage de l'animation? Ou devrais-je penser autrement?
Je ne suis pas très satisfait du max-height
solution, car la vitesse d'animation résultante sera très étrange lorsque max-height
n'est pas proche ou inférieur à height
, et la hauteur de mes composants varie beaucoup.
Je pourrais imaginer que la solution finale pourrait être un peu compliquée, mais je pense qu'en faire un Mixin sera assez agréable pour la réutiliser n'importe où
J'ai eu le même problème et j'ai fini par écrire un composant autonome pour animer la hauteur.
Vous pouvez voir la démo ici: https://stanko.github.io/react-animate-height/
Il est beaucoup plus facile à utiliser et la bibliothèque entière est vraiment petite (~ 200 lignes)
<AnimateHeight
duration={ 500 }
height={ 'auto' }
>
<h1>Your content goes here</h1>
<p>Put as many React or HTML components here.</p>
</AnimateHeight>
Désolé pour l'auto-promotion éhontée, mais je pense que cela peut vous faire gagner beaucoup de temps si vous avez plus d'un composant à animer.
À votre santé!
Après un peu plus d'expérience, j'ai trouvé une solution en utilisant l'API de bas niveau ReactTransitionGroup
au lieu de haut niveau ReactCSSTransitionGroup
Voici le JSFiddle avec une solution de travail: http://jsfiddle.net/cherrry/0wgp34cr/
Avant l'animation, il fait 3 choses:
display: none
et ajouter .anim-enter
pour régler la hauteur sur 0.anim-enter-active
Pour démarrer l'animation, cela fait 2 choses:
.anim-enter-active
pour démarrer l'animationCertains numéros et noms de classe dans JSFiddle étaient codés en dur, mais il devrait être assez facile de transformer le "mixin" en une classe React en remplacement de ReactCSSTransitionGroup
Si vous ne voulez pas importer un module ou utiliser qjuery, voici un modèle utilisant React ref ( https://reactjs.org/docs/refs-and-the-dom .html )
Fondamentalement, vous obtenez la hauteur qu'elle sera, atteignez cette hauteur, revenez à auto. Sur le chemin du retour, passez à la hauteur, puis revenez à 0.
class CollapsibleSectionBlock extends React.Component {
constructor(props) {
super(props);
this.state = {
showContent: false,
height: "0px",
myRef: null,
};
}
componentDidUpdate = (prevProps, prevState) => {
if (prevState.height === "auto" && this.state.height !== "auto") {
setTimeout(() => this.setState({ height: "0px" }), 1);
}
}
setInnerRef = (ref) => this.setState({ myRef: ref });
toggleOpenClose = () => this.setState({
showContent: !this.state.showContent,
height: this.state.myRef.scrollHeight,
});
updateAfterTransition = () => {
if (this.state.showContent) {
this.setState({ height: "auto" });
}
};
render() {
const { title, children } = this.props;
return (
<div>
<h2 onClick={() => this.toggleOpenClose()}>
Example
</h2>
<div
ref={this.setInnerRef}
onTransitionEnd={() => this.updateAfterTransition()}
style={{
height: this.state.height,
overflow: "hidden",
transition: "height 250ms linear 0s",
}}
>
{children}
</div>
</div>
);
}
}