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
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"));