这个简单的东西应该很容易实现,但是我把头发拉出来是多么复杂。
所有我想做的是动画的安装&卸载一个React组件,就是这样。这是我迄今为止所尝试的,为什么每个解决方案都无法正常工作:
> ReactCSSTransitionGroup – 我根本不使用CSS类,它们都是JS样式,所以这不行。
> ReactTransitionGroup – 这个较低级别的API是非常好的,但它需要您在动画完成时使用回调,因此只需使用CSS转换就不会在此处运行。总是有动画库,这将导致以下几点:
> GreenSock – 许可对于商业用途IMO来说太限制了。
>反应运动 – 这似乎很棒,但是TransitionMotion对我需要的是非常混乱和过于复杂的。
>当然,我可以像Material UI那样做诡计,元素被渲染但是保持隐藏(左:-10000px),但我宁愿不去那条路线。我认为它是黑客,我想要我的组件卸载,所以他们清理,而不是混乱的DOM。
我想要一些容易实现的东西。挂上,动画一套风格;在卸载时,动画相同(或另一组)样式。完成。它还必须在多个平台上具有高性能。
我在这里打砖墙。如果我缺少一些东西,有一个简单的方法来做,让我知道。
解决方法
这有点长,但我已经使用所有的本机事件和方法来实现这个动画。无反应CSSTransitionGroup,ReactTransitionGroup等
我用过的东西
>反应生命周期方法
> onTransitionEnd事件
这是如何工作的
>根据传递(安装)的mount porp安装元素,并使用默认样式(不透明度:0)
>挂载或更新后,使用componentDidMount(componentWillReceiveProps进行进一步的更新)以更改样式(不透明度:1)(超时)(以使其成为异步)。
>在卸载过程中,将一个道具传递给组件以识别卸载,再次更改样式(opacity:0),onTransitionEnd,从DOM中删除卸载元素。
继续循环。
希望这可以帮助。
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 animiation } unMountStyle() { //css for unmount animation this.setState({ style: { fontSize: 60,transition: 'all 1s ease',} }) } mountStyle() { // css for mount animation this.setState({ style: { fontSize: 60,opacity: 1,} }) } componentDidMount(){ setTimeout(this.mountStyle,10) //call the into animiation } 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>