5

I migrated from the old CSSTransitionGroup to the new react-transition-group CSSTransition and TransitionGroup.

I'm creating (hacking) an overlay loader and I'm trying to apply animation to the overlay when it appears and disappears.

Specifically when I pass an active=true props to the LoadingOverlayWrapper then a new CSSTransition is added to the TransitionGroup (the Fadecomponent) that wraps the overlay to show.

When active=false then the CSSTransition is removed from within the TransitionGroup (the direct child of TransitionGroupis null).

This is the relevant part of the code:

import React, {Children} from 'react'
import PropTypes from 'prop-types'
import {CSSTransition, TransitionGroup} from 'react-transition-group'
import LoadingOverlay from "./LoadingOverlay";
import styles from './Overlay.sass';


const FirstChild = props => Children.toArray(props.children)[0] || null;

const Fade = (props) => (
  <CSSTransition
    {...props}
    timeout={500}
    classNames={{
      appear: styles.appear,
      appearActive: styles.appearActive,
      enter: styles.enter,
      enterActive: styles.enterActive,
      exit: styles.exit,
      exitActive: styles.exitActive
    }}
  >
    <FirstChild {...props} />
  </CSSTransition>
);


class LoadingOverlayWrapper extends React.Component {

  render() {
    const {active} = this.props;

    return (
      <div>
        <TransitionGroup>
          {
            active ?
            (
              <Fade key='transition_effect'>
                <LoadingOverlay key='the_dimmer' {...this.props} />
              </Fade>
            )
            :
            null
          }
        </TransitionGroup>
        {this.props.children}
      </div>
    )
  }
}

And this is the relevant sass file (imported as css module):

.enter, .appear
  opacity: 0.01

.appearActive, .enterActive
  opacity: 1
  transition: opacity .5s ease-in

.exit, .leave
  opacity: 0.01

.exitActive, .leaveActive
  opacity: 0
  transition: opacity .5s ease-in

The enter (or appear, not sure here) transition works.

The problem is that when I remove the Fade component, being replace by null then the exit transition is not applied (or not visible) but I get no error, everything else works as intended.

I'm not sure how to debug or proceed here given I have little experience with React TransitionGroup.

Leonardo
  • 3,356
  • 2
  • 37
  • 72
  • I am running into the exact same scenario with my limited knowledge of how TransitionGroup works.. were you able to find a solution to this? – Shawn Jun 21 '18 at 05:18
  • it's been a while but as I recall no, I did not find a solution :\ – Leonardo Jun 21 '18 at 08:38

2 Answers2

1

I've been struggling with the same issue - the solution that worked for me is using the childFactory prop on the <TransitionGroup> like so:

   <TransitionGroup
     childFactory={child => React.cloneElement(child)}
   >
      {
        active ?
        (
          <Fade key='transition_effect'>
            <LoadingOverlay key='the_dimmer' {...this.props} />
          </Fade>
        )
        :
        null
      }
    </TransitionGroup>
Danielle LC
  • 116
  • 3
1
import { CSSTransition } from 'react-transition-group';

<CSSTransition
  in={toShow} // boolean value passed via state/props to either mount or unmount this component
  timeout={300}
  classNames='my-element' // IMP!
  unmountOnExit
>
  <ComponentToBeAnimated />
</CSSTransition>

NOTE: Make sure to apply below styles using the class property in CSS:

.my-element-enter {
  opacity: 0;
  transform: scale(0.9);
}
.my-element-enter-active {
  opacity: 1;
  transform: translateX(0);
  transition: opacity 300ms, transform 300ms;
}
.my-element-exit {
  opacity: 1;
}
.my-element-exit-active {
  opacity: 0;
  transform: scale(0.9);
  transition: opacity 300ms, transform 300ms;
}
anoNewb
  • 2,198
  • 16
  • 16