Ante
Ante

Reputation: 8637

Page animations with React Router 4 and React Transition Group 2.3

I'm using React Router 4 and React Transition Group 2.* and I can't set it up to make exit transition/animation on page change. If I log transition events I only get exited event which is triggered as soon I start page transition.

Fade transition:

import React, { Component } from 'react'
import Transition, {
  ENTERING,
  ENTERED,
  EXITING,
  EXITED,
} from 'react-transition-group/Transition'

// can be set globaly, just duration = 500
const duration = 300

const defaultStyle = {
  transition: `all ${duration}ms ease-in-out`,
  color: 'white',
  opacity: 0,
  marginTop: '82px',
}

const transitionStyles = {
  [ENTERING]: {
    opacity: 0,
    marginTop: '82px',
  },
  [ENTERED]: {
    opacity: 1,
    marginTop: '62px',
  },
  [EXITING]: {
    opacity: 1,
    marginTop: '62px',
  },
  [EXITED]: {
    opacity: 0,
    marginTop: '82px',
  },
}

class FadeTransition extends Component {
  handleExit = elem => {
    console.log('handleExit')
  }

  handleExiting = elem => {
    console.log('handleExiting')
  }
  render() {
    const { in: inProp, children } = this.props

    return (
      <Transition
        in={inProp}
        timeout={duration}
        appear={true}
        exit={false}
        onExit={this.handleExit}
        onExiting={this.handleExiting}
      >
        {(state, props) =>
          React.cloneElement(children, {
            ...props,
            style: {
              ...defaultStyle,
              ...transitionStyles[state],
            },
          })}
      </Transition>
    )
  }
}

export default FadeTransition

App.js file:

class App extends Component {
  render() {
    return (
      <div className="App">
        <div className="TopBar">
          <Link to="/">Home</Link>
          <Link to="/subpage">Subpage</Link>
        </div>
        <Route
          {...this.props}
          render={({ location }) =>
            <TransitionGroup component="main">
              <FadeTransition in={false}>
                <Switch location={location} key={location.key}>
                  <Route
                    exact
                    path="/"
                    children={({ match, ...rest }) => <Home {...rest} />}
                  />
                  <Route
                    path="/subpage"
                    children={({ match, ...rest }) => <Subpage {...rest} />}
                  />
                </Switch>
              </FadeTransition>
            </TransitionGroup>}
        />
      </div>
    )
  }
}

And finally, Home file:

 class Home extends Component {
  render() {
    return (
      <FadeTransition in={true} key={'home'}>
        <div className="page">
          <h1>Home</h1>
          <p>Hello from the home page!</p>
        </div>
      </FadeTransition>
    )
  }
}

Upvotes: 1

Views: 523

Answers (1)

Maor Yosef
Maor Yosef

Reputation: 99

You should add the key on the FadeTransition component so that TransitionGroup will see that a child was changed and trigger the animation

Should look something like this

<TransitionGroup className="page-animation-container">
    <FadeTransition key={location.key} in={false}>
        <Switch location={location}>
            <Route
                exact
                path="/"
                children={({ match, ...rest }) => <Home {...rest} />}
            />
            <Route
                path="/subpage"
                children={({ match, ...rest }) => <Subpage {...rest} />}
            />
        </Switch>
    </FadeTransition>
</TransitionGroup>

Upvotes: 2

Related Questions