简体   繁体   中英

React animate fade-in and fade-out with CSSTransitionGroup on conditionally rendered component

I have a card component that conditionally renders a check icon when this.state.isSelected is true . I want to animate the check icon when it renders. I also want to animate it when it leaves.

I have the following class component:

import { CSSTransitionGroup } from 'react-transition-group';

export default class AdoptablesFilterCard extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isSelected: false,
      cardHeader: props.cardHeader,
      cardType: props.cardType,
    }

    //Click handler binding
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick = (e) => { //switches the state 'isSelected' when clicked
    this.setState((prevState) => ({
      isSelected: !prevState.isSelected
    }))
  }

  render() {
    const {isSelected} = this.state;
    // let check;
    // {isSelected ? 
    const check = <i className="far fa-check-circle" 
                             key={this.state.cardHeader}></i>;

                             //:
                             //check = <div key={this.state.cardHeader}></div>}

    return (
      <div className="adoptables-filter-card" onClick={this.handleClick} ref={this.myRef}>
        <div className="adoptables-filter-card-header">
          {this.props.cardHeader}
        </div>

        <div className="adoptables-filter-card-body">
          {(() => {
            switch (this.props.cardType) {
              case "animal": return(<i className={`fas fa-${this.props.cardHeader}`}></i>)
              case "color": return(<div className="color-splotch" style={{background: this.props.cardHeader}}></div>)
            }
          })()}
        </div>

        {isSelected ? <CSSTransitionGroup
                        transitionName="icon"
                        transitionAppear={true}
                        transitionAppearTimeout={3000}
                        transitionEnter={false}
                        transitionLeave={false}>
                        {check}
                      </CSSTransitionGroup>
                      : null} 
      </div>
    )
  }
}

and the CSS classes for CSSTransitionGroup:

.icon-appear {
  opacity:  0.01;
}

.icon-appear.icon-appear-active {
  opacity: 1;
  // transform: rotateY(360deg);
  transition: opacity 3000ms ease-in;
}

This code works for rendering the check icon when the card is clicked and applying the animation (the 3000ms is so I can make sure it's there and activating). When the card is clicked again (de-selected) the check icon immediately disappears. I'd like to fade-out the check icon at this stage.

I found this while searching for an answer: https://stackoverflow.com/questions/46916118/conditional-rendering-and-reactcsstransitiongroup-animation# = . You can see where I've commented out the conditional assignment of 'check'. It renders/hides the check icon, but the animation is not applied.

You can useCSSTransition . Replace this

{isSelected ? <CSSTransitionGroup
                    transitionName="icon"
                    transitionAppear={true}
                    transitionAppearTimeout={3000}
                    transitionEnter={false}
                    transitionLeave={false}>
                    {check}
                  </CSSTransitionGroup>
                  : null} 

by

<CSSTransition 
    unmountOnExit
    in={isSelected}
    timeout={2000}
    classNames="icon">
    {check}
</CSSTransition>

style.css

.icon-enter {
   opacity: 0;
}
.icon-enter-active {
  opacity: 1;
  transition: opacity 2000ms;
}
.icon-exit {
  opacity: 1;
}
.icon-exit-active {
  opacity: 0;
  transition: opacity 2000ms;
}

You can see in CodeSandBox . Hope it helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM