React - animate mount and unmount of a single component

前端 未结 16 1658
南笙
南笙 2020-12-22 16:34

Something this simple should be easily accomplished, yet I\'m pulling my hair out over how complicated it is.

All I want to do is animate the mounting & unmounti

16条回答
  •  执笔经年
    2020-12-22 16:53

    This is a bit lengthy but I've used all the native events and methods to achieve this animation. No ReactCSSTransitionGroup, ReactTransitionGroup and etc.

    Things I've used

    • React lifecycle methods
    • onTransitionEnd event

    How this works

    • 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.

    Continue the cycle.

    Go through the code, you'll understand. If any clarification is needed, please leave a comment.

    Hope this helps.

    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 && 

    Hello

    } } 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
    } } ReactDOM.render(, document.getElementById('app'))
    
    
    

提交回复
热议问题