Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 235
Yuri Visovsiouk Avatar asked Oct 24 '17 16:10

Yuri Visovsiouk


People also ask

What is conditional rendering?

In React, you can create distinct components that encapsulate behavior you need. Then, you can render only some of them, depending on the state of your application. Conditional rendering in React works the same way conditions work in JavaScript.

Can you use CSS animations in React?

We can create our own CSS animations through the use of keyframes which will allow us to define our animation sequences for each element. We then use that keyframe into the CSS animation property and attach it to a particular element.

How do you use CSSTransition?

To work, CSSTransition applies a pair of class names during the appear , enter , and exit states of the transition. The first class is applied and then a second *-active class in order to activate the CSS transition. After the transition, matching *-done class names are applied to persist the transition state.


2 Answers

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.

like image 66
jered Avatar answered Oct 01 '22 22:10

jered


Here is a snippet from my code

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

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

            ) : '' }
            </CSSTransitionGroup>
     )
}
like image 32
artSir Avatar answered Oct 01 '22 23:10

artSir