reactjsreact-routerreact-motion

React Router v4 Match transitions using React Motion


I'm loving RR4 and RM, there's already great examples for React Router V4 (https://github.com/ReactTraining/react-router/tree/v4/website/examples) but i'm struggling to understand how I can use the new V4 API to transition between different Matches in my Router with React Motion, fading in and out between my 'pages'.

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?

<Router>
  <div>
    <Match pattern="/products" component={Products} />
    <Match pattern="/accessories" component={Accessories} />
  </div>
</Router>

Any help would be greatly appreciated.


Solution

  • From the linked example we can simplify. First we create a wrapper component that will replace the <Match/> tag and wrap it's component:

    import React from 'react'
    import { Match } from 'react-router'
    import { TransitionMotion, spring } from 'react-motion'
    
    const styles = {}
    
    styles.fill = {
      position: 'absolute',
      left: 0,
      right: 0,
      top: 0,
      bottom: 0
    }
    
    const MatchTransition = ({ 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: 1 },
              data: props
            } ] : []}
          >
            {interpolatedStyles => (
              <div>
                {interpolatedStyles.map(config => (
                  <div
                    key={config.key}
                    style={{ ...styles.fill, ...config.style }}
                  >
                    <Component {...config.data} />
                  </div>
                ))}
              </div>
            )}
          </TransitionMotion>
        )} />
      )
    }
    
    export default MatchTransition
    

    Then we use it like this:

    <MatchTransition pattern='/here' component={About} />
    <MatchTransition pattern='/there' component={Home} />