Animation on unmount with React and react-transition-group
It is expected, because as the state is changed, the animation is not started yet, but the children already gone.
So it is like magically instant disappear. Well we just need to hide it right? remove the conditional render.
I checked, the node removed automatically after animation is done. So no need to use conditional render. Luckily! The code become:
import React from "react";
import ReactDOM from "react-dom";
import { CSSTransition } from "react-transition-group";
import "./styles.css";
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
logoIntro: true,
mounted: false
};
}
componentDidMount() {
this.setState({
mounted: true
});
}
render() {
return (
<div className="root">
<CSSTransition
in={this.state.mounted}
appear={true}
unmountOnExit
classNames="fade"
timeout={1000}
>
<div>
<button
onClick={() => {
this.setState({
mounted: !this.state.mounted
});
}}
>
Remove
</button>
<div>SOME COMPONENT</div>
</div>
</CSSTransition>
</div>
);
}
}
ReactDOM.render(<Example />, document.getElementById("root"));
Admin
Updated on June 27, 2022Comments
-
Admin almost 2 years
I am working with React, and I'm trying to create a
Fade
component with React-transition-group to fade in and fade out an element depending on a condition stored in the state: http://reactcommunity.org/react-transition-group/css-transition/This is what I have right now:
import React from "react"; import ReactDOM from "react-dom"; import { CSSTransition } from "react-transition-group"; import "./styles.css"; class Example extends React.Component { constructor(props) { super(props); this.state = { mounted: false }; } componentDidMount() { setTimeout(() => { this.setState({ mounted: true }); }, 10); } render() { return ( <div className="root"> <CSSTransition in={this.state.mounted} appear={true} unmountOnExit classNames="fade" timeout={1000} > {this.state.mounted ? ( <div> <button onClick={() => { this.setState({ mounted: !this.state.mounted }); }} > Remove </button> <div>COMPONENT</div> </div> ) : ( <div /> )} </CSSTransition> </div> ); } }
Here is the CSS
.fade-enter { opacity: 0; transition: opacity .5s ease; } .fade-enter-active { opacity: 1; transition: opacity .5s ease; } .fade-exit { opacity: 1; transition: opacity .5s ease; } .fade-exit-active { opacity: 0; transition: opacity .5s ease; }
When the component is mounted there is a transition in opacity from 0 to 1 with .5s. But when its unmounted, it is not animated: the component dissapear without transition.
I made a sandbox with this component to test it: https://codesandbox.io/s/k027m33y23 I am sure that this is a common case, but I can't find a way to animate the component on the unmount. If anyone has any idea it will be very welcome!
-- EDIT -- As @IPutuYogaPermana said, the conditional rendering inside CSSTransition is not neccesary. So this:
{this.state.mounted ? ( <div> <button onClick={() => { this.setState({ mounted: !this.state.mounted }); }} > Remove </button> <div>COMPONENT</div> </div> ) : ( <div /> )}
Should be like this:
<div> <button onClick={() => { this.setState({ mounted: !this.state.mounted }); }} > Remove </button> <div>COMPONENT</div> </div>
The component will be automatically mounted or unmounted depending on the
in
attribute in the CSSTransition component. Here the final code in a codesandbox: https://codesandbox.io/s/62m86nm7qw -
Admin over 5 yearsThanks @IPutuYogaPermana You mean that "react-transition-group" doesn't take care of this case, and I have to implement it by myself? Is strange, because is a very common case, right?
-
I Putu Yoga Permana over 5 yearswell, actually the problem is because the children node is removed, even before the animation started. Need a better workaround tho.
-
Admin over 5 yearsOk, I get that. But then, apart of this solution, which would be the most common way of doing a fade out animation just before unmount?
-
I Putu Yoga Permana over 5 yearsi update my answer, i just realize, the problem is because the child node has conditional render. Just remove the conditional render. So when animation is done, the children removed automatically.
-
Admin over 5 yearsAaah, so this is the magic with CSSTransition! No need of conditional rendering… good! By the way, even when your code works on CodeSandbox, it fails in the snippet; I don't know if it should work there...
-
I Putu Yoga Permana over 5 yearsI am not familiar with how SO snippets. Only to show the sample code. Please mark this as accepted answer, if this solve your problem ;) @AdCorrea