I'm trying to use React Motion UI Pack to animate the slide-in/slide-out animation for my Side Navigation. This is it:
constructor(props){
super(props);
this.state = {
isThere: false,
showOverlay: false
}
this.updatePredicate = this.updatePredicate.bind(this);
this.handleToggleClick = this.handleToggleClick.bind(this);
this.handleOverlayClick = this.handleOverlayClick.bind(this);
}
componentDidMount() {
this.updatePredicate();
window.addEventListener("resize", this.updatePredicate);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updatePredicate);
}
updatePredicate() {
this.setState({ isThere: window.innerWidth > this.props.breakWidth })
}
handleToggleClick(){
this.setState({
isThere: true,
showOverlay: true
})
}
handleOverlayClick(){
this.setState({
isThere: false,
showOverlay: false
});
}
let sidenav = (
<Tag {...attributes} className={classes} key="sidenav">
<ul className="custom-scrollbar">
{src &&
<li>
<div className="logo-wrapper">
<a href={href}>
<img src={src} className="img-fluid"/>
</a>
</div>
</li>
}
{children}
</ul>
</Tag>
);
return (
<div>
{ isThere ? (
<Transition
component={false}
appear={{ opacity: 0.2, translateX: -300 }}
enter={{ opacity: 1, translateX: 0 }}
leave={{ opacity: 0.2, translateX: -300 }}
>
{ sidenav }
</Transition>
) : (
<Button color="primary" onClick={this.handleToggleClick} key="sideNavToggles">ClickMe</Button>
) }
{showOverlay && (
<div id="sidenav-overlay" onClick={this.handleOverlayClick} key="overlay"></div>
)}
</div>
);
}
}
The utility seems awesome, yet there is something I cannot wrap my head around. My component renders button or the sidenav depending on the breakWith
prop. Clicking on the rendered button causes the SideNav to slide-in anyway, this time together with an overlay. Transition
allowed for a smooth slide-in animation, but now I would like to apply a slide-out one upon clicking on the overlay.
Few hours passed and I'm starting to think it is impossible. Rendering of components is conditional & state-based (the isThere ? (...
part in render()
), right? As the pack offers no willLeave
props, there seems to be no time to animate the leave
in between the change of state and the re-render with the conditionally-rendered element already missing.
Or am I missing something?
yes - the answer found here effectively addresses the problem. To solve it, I moved the conditional logic of the component up, created appropriate variable, and encapsulated it inside a <Transition>
in render()
. If there is a lesson to be learned here, it is that <Transition>
from Reakt Motion UI Pack (and, perhaps, elsewhere) does not fire its leave
animation if surrounded by a conditional statement, making it impossible to use it together with ternary operator
if you don't want the false
component to be animated as well.