反应-动画化单个组件的安装和卸载 [英] React - animate mount and unmount of a single component
问题描述
这个简单的事情应该很容易完成,但是我要把它的复杂性弄出来。
Something this simple should be easily accomplished, yet I'm pulling my hair out over how complicated it is.
我要做的就是为安装和放大动画。 ;卸载React组件就可以了。这是到目前为止我一直在尝试的原因,以及每个解决方案都不起作用的原因:
All I want to do is animate the mounting & unmounting of a React component, that's it. Here's what I've tried so far and why each solution won't work:
-
ReactCSSTransitionGroup
-我根本不使用CSS类,因为它们都是JS样式,所以这行不通。 -
ReactTransitionGroup
-这个较低级别的API很棒,但是它要求您在动画完成后使用回调,因此仅使用CSS过渡在此处无效。总是有动画库,这引出了下一个问题: - GreenSock-许可对于业务使用IMO而言过于严格。
- React Motion-这似乎很棒,但是
TransitionMotion
令我非常困惑,而且过于复杂。 - 我当然可以像Material一样做些诡计UI可以,其中的元素已呈现但仍处于隐藏状态(
left:-10000px
),但我宁愿不走那条路线。我认为它很hacky,并且我想要卸下我的组件,以便它们清理并不会使DOM混乱。
ReactCSSTransitionGroup
- I'm not using CSS classes at all, it's all JS styles, so this won't work.ReactTransitionGroup
- This lower level API is great, but it requires you to use a callback when the animation is complete, so just using CSS transitions won't work here. There are always animation libraries, which leads to the next point:- GreenSock - The licensing is too restrictive for business use IMO.
- React Motion - This seems great, but
TransitionMotion
is extremely confusing and overly complicated for what I need. - Of course I can just do trickery like Material UI does, where the elements are rendered but remain hidden (
left: -10000px
) but I'd rather not go that route. I consider it hacky, and I want my components to unmount so they clean up and are not cluttering up the DOM.
我想要实现简单的功能。在坐骑上,设置一组样式的动画;卸载时,为一组相同(或另一组)样式设置动画。做完了在多个平台上也必须具有高性能。
I want something that's easy to implement. On mount, animate a set of styles; on unmount, animate the same (or another) set of styles. Done. It also has to be high performance on multiple platforms.
我在这里遇到了麻烦。如果我缺少某些东西,并且有一种简单的方法可以做到这一点,请告诉我。
I've hit a brick wall here. If I'm missing something and there's an easy way to do this, let me know.
推荐答案
这有点冗长,但是我已经使用了所有本机事件和方法来实现此动画。没有 ReactCSSTransitionGroup
, ReactTransitionGroup
等。
This is a bit lengthy but I've used all the native events and methods to achieve this animation. No ReactCSSTransitionGroup
, ReactTransitionGroup
and etc.
我使用过的东西
- 反应生命周期方法
-
onTransitionEnd
事件
- React lifecycle methods
onTransitionEnd
event
工作原理
- 根据已通过的mount prop(
mount )和默认样式(
opacity:0
) - 安装或更新后,使用
componentDidMount
(componentWillReceiveProps
进行进一步更新)以更改样式(不透明度:1
),并带有超时(使其异步)。 - 在卸载期间,将道具传递给组件以识别卸载,然后再次更改样式(
opacity:0
),onTransitionEnd
,从DOM中删除该元素。
- Mount the element based on the mount prop passed(
mounted
) and with default style(opacity: 0
) - After mount or update, use
componentDidMount
(componentWillReceiveProps
for further updates)to change the style (opacity: 1
) with a timeout(to make it async). - During unmount, pass a prop to the component to identify unmount, change the style again(
opacity: 0
),onTransitionEnd
, remove unmount the element from the DOM.
继续循环。
遍历代码,您会明白的。
Go through the code, you'll understand. If any clarification is needed, please leave a comment.
希望这会有所帮助。
class App extends React.Component{
constructor(props) {
super(props)
this.transitionEnd = this.transitionEnd.bind(this)
this.mountStyle = this.mountStyle.bind(this)
this.unMountStyle = this.unMountStyle.bind(this)
this.state ={ //base css
show: true,
style :{
fontSize: 60,
opacity: 0,
transition: 'all 2s ease',
}
}
}
componentWillReceiveProps(newProps) { // check for the mounted props
if(!newProps.mounted)
return this.unMountStyle() // call outro animation when mounted prop is false
this.setState({ // remount the node when the mounted prop is true
show: true
})
setTimeout(this.mountStyle, 10) // call the into animation
}
unMountStyle() { // css for unmount animation
this.setState({
style: {
fontSize: 60,
opacity: 0,
transition: 'all 1s ease',
}
})
}
mountStyle() { // css for mount animation
this.setState({
style: {
fontSize: 60,
opacity: 1,
transition: 'all 1s ease',
}
})
}
componentDidMount(){
setTimeout(this.mountStyle, 10) // call the into animation
}
transitionEnd(){
if(!this.props.mounted){ // remove the node on transition end when the mounted prop is false
this.setState({
show: false
})
}
}
render() {
return this.state.show && <h1 style={this.state.style} onTransitionEnd={this.transitionEnd}>Hello</h1>
}
}
class Parent extends React.Component{
constructor(props){
super(props)
this.buttonClick = this.buttonClick.bind(this)
this.state = {
showChild: true,
}
}
buttonClick(){
this.setState({
showChild: !this.state.showChild
})
}
render(){
return <div>
<App onTransitionEnd={this.transitionEnd} mounted={this.state.showChild}/>
<button onClick={this.buttonClick}>{this.state.showChild ? 'Unmount': 'Mount'}</button>
</div>
}
}
ReactDOM.render(<Parent />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
这篇关于反应-动画化单个组件的安装和卸载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!