React-transition-group

Bug report

by JohnAlbin

HTML

<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-transition-group/2.4.0/react-transition-group.min.js"></script>
<div id="example">
  <!-- This element's contents will be replaced with your component. -->
</div>

CSS

body,
.toggleButton {
  font-family: verdana;
  font-size: 24px;
  padding: 5px 10px;
}

.wrapper {
  position: relative;
  min-height: 1rem;
  margin: 1rem;
  border: 1px dotted grey;
  overflow: hidden;
}

.element {
  padding: 1rem;
  color: white;
  background-color: purple;
  transition-property: background-color, transform;
  transition-duration: 4s;
}

.shift-enter {
  background-color: white;
  transform: translate3d(-100%, 0, 0);
}

.shift-enter-active,
.shift-enter-done,
.shift-exit {
  background-color: purple;
  transform: translate3d(0, 0, 0);
}

.shift-exit-active {
  background-color: white;
  transform: translate3d(-100%, 0, 0);
}

Babel + JSX

const { CSSTransition } = ReactTransitionGroup;

class Child extends React.Component {
  componentDidMount() {
    document.querySelector('body').getClientRects();
  }

  render() {
    return (
      <div className={this.props.className}>
        {this.props.children}
      </div>
    );
  }
}

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = { toggle: false };
  }

  toggleTransition = () => {
    this.setState({
      toggle: !this.state.toggle,
    });
  };

  render() {
    return (
      <div>
        <button className="toggleButton" onClick={this.toggleTransition}>
          Toggle Transition
        </button>

        <div className="wrapper">
          <CSSTransition
            in={this.state.toggle}
            timeout={4000}
            className="element"
            classNames="shift"
            mountOnEnter
            unmountOnExit
          >
            <div>Ex. 1: child is HTML element</div>
          </CSSTransition>
        </div>

        <div className="wrapper">
          <CSSTransition
            in={this.state.toggle}
            timeout={4000}
            className="element"
            classNames="shift"
            mountOnEnter
            unmountOnExit
          >
            <Child>Ex. 2: child calls DOM on componentDidMount()</Child>
          </CSSTransition>
        </div>

        <div className="wrapper">
          <CSSTransition
            in={this.state.toggle}
            timeout={4000}
            // Add the "shift-enter" styles to the default CSS state.
            className="element shift-enter"
            classNames="shift"
            mountOnEnter
            unmountOnExit
          >
            <Child>Ex. 3: same as #2 but CSSTransition has work-around</Child>
          </CSSTransition>
        </div>

      </div>
    );
  }
}

ReactDOM.render(
  <Example />,
  document.getElementById('example')
);