React Router v4 Animated Transition Example

react router 4 page transitions
react native-router animation
react slide transition
react-router transitionto
react-transition-group modal example
react-transition-group slide
react router redirect transition
react router api

The animation transition example provided in the v4 docs seems a little convoluted to me, since it depicts fading the same component in and out and adjusting the background color.

I'm trying to apply this technique to a more real-world example of fading one component out and another in, however I can't get it to work properly (it only seems to fade the first one out, then the second one pops in, and this transition only works one way (back button results in no transition).

Here's my code, which uses a stripped down version of MatchWithFade from the example:

import React from 'react';
import { TransitionMotion, spring } from 'react-motion'
import { HashRouter, Match, Miss } from 'react-router';
import Home from './components/Home';
import Player from './components/Player';
import FormConfirmation from './components/FormConfirmation';

const App = () => (
  <HashRouter>
    <div className="App">
      <MatchWithFade exactly pattern="/" component={Home} />

      <MatchWithFade pattern="/player/:playerId" component={Player} />

      <MatchWithFade pattern="/entered" component={FormConfirmation} />

      <Miss render={(props) => (
        <Home players={Players} prizes={Prizes} {...props} />
      )} />
    </div>
  </HashRouter>
);

const MatchWithFade = ({ component:Component, ...rest }) => {
  const willLeave = () => ({ zIndex: 1, opacity: spring(0) })

  return (
    <Match {...rest} children={({ matched, ...props }) => (
      <TransitionMotion
        willLeave={willLeave}
        styles={matched ? [ {
          key: props.location.pathname,
          style: { opacity: spring(1) },
          data: props
        } ] : []}
      >
        {interpolatedStyles => (
          <div>
            {interpolatedStyles.map(config => (
              <div
                key={config.key}
                style={{...config.style}}
              >
                <Component {...config.data}/>
              </div>
            ))}
          </div>
        )}
      </TransitionMotion>
    )}/>
  )
}

export default App;

I realize that this question is nearly a duplicate of this one, however that one has an accepted answer that doesn't actually answer the question.

react-motion is not good for large applications. Use react-transition-group instead.

Because react-motion use javascript to perform the transition. When making API call the transition will cross path(sync call in js) and make the transition laggy when route to new page. Where as react-transition-group use CSS to perform the transition.

Step by step guide of simple routing transition effect for React, Former versions before React Router v4, it was following so-called “static For example, if you defined classNames props as 'fade', the classNames such as  Animating Route Transitions with React Router. React Router v4 provides an intuitive, declarative API for building React apps that support navigation. However, there is not much in the docs, stack-overflow, or blogs that explain how to animate between routes when building UIs that require motion.

The v4 docs have moved to react-transition-group so you may consider to do the same.

With regards to "fading the same component in and out" it's not really the same instance of the Component. Two instances exist simultaneously and can provide the cross-fade. react-motion docs says "TransitionMotion has kept c around" and I imagine react-transition-group is the same.

Animated Transitions with React Router, If you're reading this you've probably discovered that React Router doesn't come down the 'Animated Transitions' example on the React Router docs. are going to render the components we create in steps #4 and #5. The React Router documentation recommends using react-transition-group. react-transition-group is a small library that can help with handling animations using React.

Here's an updated solution using react 16 and ReactCSSTransitionGroup from "react-addons-css-transition-group"

index.js

import React, { Component } from "react";
import ReactCSSTransitionGroup from "react-addons-css-transition-group";
import { render } from "react-dom";
import "./main.css";

function* continuosArrayIterator(arr) {
  let idx = 0;
  while (idx < arr.length) {
    let ret = arr[idx];
    idx++;
    if (idx === arr.length) {
      idx = 0;
    }
    yield ret;
  }
}

class App extends Component {
  constructor() {
    super();
    this.clickHandler = this.clickHandler.bind(this);
    this.items = [
      {
        id: 1,
        text: "item1",
        img: "https://mirrors.creativecommons.org/presskit/icons/cc.large.png"
      },
      {
        id: 2,
        text: "item2",
        img: "https://mirrors.creativecommons.org/presskit/icons/by.large.png"
      },
      {
        id: 3,
        text: "item3",
        img: "https://mirrors.creativecommons.org/presskit/icons/nc.large.png"
      },
      {
        id: 4,
        text: "item4",
        img:
          "https://mirrors.creativecommons.org/presskit/icons/nc-eu.large.png"
      }
    ];
    this.imageIterator = continuosArrayIterator(this.items);
    this.state = {
      image: this.imageIterator.next().value
    };
  }

  clickHandler(event) {
    return this.setState({
      image: this.imageIterator.next().value
    });
  }

  render() {
    return (
      <div>
        <button onClick={this.clickHandler}>Next Image</button>
        <ReactCSSTransitionGroup
          transitionAppear={true}
          transitionLeaveTimeout={500}
          transitionEnterTimeout={500}
          className="container"
          transitionName="example"
        >
          <div
            key={this.state.image.id}
            style={{
              position: "absolute",
              backgroundImage: `url(${this.state.image.img}`,
              backgroundSize: "auto 100px",
              height: "100px",
              width: "100px"
            }}
          />
        </ReactCSSTransitionGroup>
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

main.css

.container {
  position: absolute;
}

.example-enter {
  opacity: 0.01;
}

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

.example-leave {
  opacity: 1;
}

.example-leave.example-leave-active {
  opacity: 0.01;
  transition: opacity 500ms ease-in;
}

.example-appear {
  opacity: 0.01;
}

.example-appear.example-appear-active {
  opacity: 1;
  transition: opacity 0.5s ease-in;
}

Animating Route Transitions with React Router, React Router v4 provides an intuitive, declarative API for building All the examples for this article are available in Codesandbox.io but in a  React-Router v4 Animated transitions of react-router v4 routes is supported with two caveats shown in the example below: The current location must be applied to the Switch to force it to maintain the previous matched route on the leaving component.

Animated Transitions with React Router v4, react-motion is not good for large applications. Use react-transition-group instead​. Because react-motion use javascript to perform the transition. When making  I'm using React Router v4 and react-transition-group v2 to test the page sliding animation. const RouterMap = => ( <Router> <Route render={({ location }) => <

React Router v4 Animated Transition Example, So, let's animate! The first animation we'll add is a simple fade transition. When a user clicks a link, we want to fade the existing  The exiting transition of state A does not depend only from state A (“dynamic transition”) Although a simple example is available on react-router doc, it is not easy to tweak it to create more sophisticated use cases such as dynamic transitions. In this article, I’ll explain how to do so thanks to react-router v4 and react-transition

Tutorial: React Router 4, A thin layer over react-motion for animating routes in react-router. Installation. npm install --save react-router-transition react-router-dom. Example Usage. import { BrowserRouter as Router, Route } from 'react-router-dom';. I've tried to understand how the Transition example works with the MatchWithFade but I'm missing how to take this and apply it to multiple matches representing my page structure. As an example: given two routes setup in my Router how can I have the mounting and unmounting handled by react-motion with TransitionMotion?

Comments
  • I'm not particularly familiar with react-motion, but it looks like <TransitionMotion> has a willEnter prop. Have you tried using that?
  • Just a wild guess: Do you have fixed/absolute position set ?
  • I'm not too familiar with react-motion either, but looking at your code, I wonder if it has to do with the z-index you're trying to transition. Your default styles for the TransitionMotion component don't have a z-index, so this could be borking the transition. Try replacing that line with something like: style: { zIndex: 2, opacity: spring(1) } -- I don't know if the spring bit is necessary? But you may want to try wrapping your z-indexes with that as well.
  • The first link is dead. Which demo are you referring to?
  • @newguy looks like the domain for their docs changed, I went ahead and updated the link so it should work now. I submitted this question over a year ago, however, so it's very likely that other things are also out of date as well.
  • Thanks @Jayen, that makes sense. I submitted this question over a year ago, so it's more than likely very out of date. I personally am no longer looking for a solution to this problem, however I'm leaving it open as it still seems to receive a decent amount of traffic which leads me to believe that others are also looking for a better example than the docs provide.
  • Thank you for your submission, however I don't see how it relates to transition animations between routes with react-router. I submitted this question over a year ago, so it's more than likely very out of date. I personally am no longer looking for a solution to this problem, however I'm leaving it open as it still seems to receive a decent amount of traffic which leads me to believe that others are also looking for a better example than the docs provide.