如何为条件渲染的组件设置动画?
How to animate conditionally-rendered components?
我正在尝试使用 React Motion UI Pack 为侧边导航制作 slide-in/slide-out 动画。就是这样:
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>
);
}
}
该实用程序看起来很棒,但有些事情我无法理解。我的组件根据 breakWith
道具呈现按钮或 sidenav。单击呈现的按钮会导致 SideNav 滑入,这次是与叠加层一起滑入。 Transition
允许平滑的滑入动画,但现在我想在单击叠加层时应用滑出动画。
几个小时过去了,我开始觉得这是不可能的。组件的渲染是有条件的和基于状态的(render()
中的 isThere ? (...
部分),对吧?由于包不提供 willLeave
道具,似乎没有时间在状态更改和重新渲染之间为 leave
设置动画,条件渲染元素已经丢失。
还是我遗漏了什么?
yes - 找到的答案 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(也许还有其他地方)如果被条件语句包围,则不会触发其 leave
动画,因此无法将其与 [=14 一起使用=] 如果您不希望 false
组件也具有动画效果。
我正在尝试使用 React Motion UI Pack 为侧边导航制作 slide-in/slide-out 动画。就是这样:
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>
);
}
}
该实用程序看起来很棒,但有些事情我无法理解。我的组件根据 breakWith
道具呈现按钮或 sidenav。单击呈现的按钮会导致 SideNav 滑入,这次是与叠加层一起滑入。 Transition
允许平滑的滑入动画,但现在我想在单击叠加层时应用滑出动画。
几个小时过去了,我开始觉得这是不可能的。组件的渲染是有条件的和基于状态的(render()
中的 isThere ? (...
部分),对吧?由于包不提供 willLeave
道具,似乎没有时间在状态更改和重新渲染之间为 leave
设置动画,条件渲染元素已经丢失。
还是我遗漏了什么?
yes - 找到的答案 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(也许还有其他地方)如果被条件语句包围,则不会触发其 leave
动画,因此无法将其与 [=14 一起使用=] 如果您不希望 false
组件也具有动画效果。