Yuri Visovsiouk
Yuri Visovsiouk

Reputation: 147

Conditional Rendering and ReactCSSTransitionGroup Animation

I've made a small app that renders different components based on a Redux state. I want to apply a "fade" animation when one of the component renders. However, for some reason, it doesn't work for me. Here's what I have so far:

content.js

class Content extends Component {
  render() {
    const transitionOptions = {
      transitionName: "fade",
      transitionEnterTimeout: 500,
      transitionLeaveTimeout: 500
    }

    if (this.props.page === 'one') {
      return (
        <div>
          <ReactCSSTransitionGroup {...transitionOptions}>
            <Comp1/>
          </ReactCSSTransitionGroup>
        </div>
      );
    } else {
      return (
        <div>
          <ReactCSSTransitionGroup {...transitionOptions}>
            <Copm2/>   
          </ReactCSSTransitionGroup>
        </div>
      );
    } 
  }
}

style.css

.fade-enter {
  opacity: 0.01;
}

.fade-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}

.fade-leave {
  opacity: 1;
}

.fade-leave.fade-leave-active {
  opacity: 0.01;
  transition: opacity 300ms ease-in;
}

I've seen ReactCSSTransitionGroup being used for items being added and removed to a list, but I haven't found one example of it being used for conditional rendering. Is it achievable? Maybe there's another addon that does this?

Upvotes: 6

Views: 10634

Answers (2)

artSir
artSir

Reputation: 550

Here is a snippet from my code

render() {       
    return (
            <CSSTransitionGroup
                transitionName="slide"
                transitionEnterTimeout={500}
                transitionLeaveTimeout={500}
            >
            { id === targetID ? (

                <div>
                    <SectionList id={id} />
                </div>

            ) : '' }
            </CSSTransitionGroup>
     )
}

Upvotes: 1

jered
jered

Reputation: 11581

I've seen this same problem posted many times. In short: you need to conditionally render the children inside of <ReactCSSTransitionGroup>, not <ReactCSSTransitionGroup> itself. <ReactCSSTransitionGroup> needs to mount once and then stay, it's the children that get added and removed.

content.js

class Content extends Component {
  render() {
    const transitionOptions = {
      transitionName: "fade",
      transitionEnterTimeout: 500,
      transitionLeaveTimeout: 500
    }

    let theChild = undefined;
    if (this.props.page === 'one') {
        theChild = <Comp1 key="comp1" />;
    } else {
        theChild = <Comp2 key="comp2" />;
    } 

    return (
        <div>
          <ReactCSSTransitionGroup {...transitionOptions}>
            {theChild}
          </ReactCSSTransitionGroup>
        </div>
    );
  }
}

Note that you should also add a unique key prop to each child inside of a <ReactCSSTransitionGroup>. That helps the component identify which children are unique in order to properly animate them in and out.

Upvotes: 7

Related Questions