2

I want to create a transition animation for react router, but it's seems doesn't work (there is no transitions).

As you can see below, all what i did is create a component FadeRoute which use ReactCSSTransitionGroup to create an animation, then i use it in switch component of react-router-dom

Here my react code

import { BrowserRouter as Router,  Switch, Route } from "react-router-dom";
import {  browserHistory } from "react-router";
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'


function FadeRoute({ component: Component, ...rest }) {
    return (
        <Route {...rest} children={({ location, match }) => (
            <ReactCSSTransitionGroup   
                    transitionName="fade"
                    transitionEnterTimeout={300}
                    transitionLeaveTimeout={300}>
            <Component />
        </ReactCSSTransitionGroup>
    )
} />
        );
    }


class App extends React.Component {

    render() {
        return (

            <Router history={browserHistory}>
                <Switch>
                    <FadeRoute exact path="/" component={Home} />
                    <FadeRoute exact path="/NextComponent" component={NextComponent} />
                    <FadeRoute component={NoMatch} />
                </Switch>
            </Router>

        );
    }

}

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

Here the css code

.fade-enter {
  opacity: 0.01;
}

.fade-enter.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;
}

could you please help me to find the where is the pb? thank you in advance

MrGildarts
  • 833
  • 1
  • 10
  • 25

2 Answers2

1

I have managed to get this to work by wrapping the whole Switch in a component that manages the CSSTransitionGroup. CSSTransitionGroup needs to temporarily render 2 routes at the same time to be able to fade between them, so it needs to sit at a higher level.

class Fade extends Component {

    render() {
        return (
            <Route render={({location}) => (
                <CSSTransitionGroup
                    transitionName="fade"
                    transitionEnterTimeout={200}
                    transitionLeaveTimeout={200}
                >
                    {React.cloneElement(this.props.children, {location: location, key: location.key})}
                </CSSTransitionGroup>
            )}/>
        );
    }
}


class App extends Component {

    render() {
        return (
            <BrowserRouter>
                <Fade>
                    <Switch>
                        <Route exact path="/" component={Home}/>
                        <Route path="/portfolio" component={Portfolio}/>
                        <Route path="/contact" component={Contact}/>
                        <Route component={NoMatch}/>
                    </Switch>
                </Fade>
            </BrowserRouter>
        );
    }
}
RichardY
  • 46
  • 1
  • 4
  • Thank you, it's working if we wrap all the switch, but we can't personalize it (change type of transition group for each route: ex fade, slide ...) – MrGildarts May 30 '17 at 13:52
  • 1
    Might not be the most elegant solution, but you could change your transitionName based on the location prop in the Fade component... Can't think of a better way right now. – RichardY May 30 '17 at 14:02
  • I see, by adding for example a switch in Fade component to check location.pathname and return transitionName depending of the case, it can be a solution thnx again – MrGildarts May 30 '17 at 15:08
1

I deal with that with similar solution like @RichardY and I published Component combinating and and you can use there all the transition* params...

https://github.com/melounek/switch-css-transition-group

EDIT: so you can use it like this:

import SwitchCSSTransitionGruoup from 'switch-css-transition-group'
// ...
<SwitchCSSTransitionGruoup
  transitionName="fade"
  transitionEnterTimeout={300}
  transitionLeaveTimeout={300}>
  <Route exact path="/" component={Home}/>
  <Route path="/portfolio" component={Portfolio}/>
  <Route path="/contact" component={Contact}/>
  <Route component={NoMatch}/>
</SwitchCSSTransitionGruoup >
Melounek
  • 764
  • 4
  • 20
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Sneha Jul 18 '17 at 12:05