Sliding React Components

Yesterday I talked about animating page changes using React Router and ReactCSSTransitionGroup. Today’s post is about how you can slide the new component in (and the old one out).

The Components

ReactCSSTransitionGroup uses the component key to determine which child components have entered, left or stayed:

import React from 'react';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import BackgroundImage from './BackgroundImage';

class App extends React.Component {
render() {
    let page = this.props.location.pathname.substr(1);
if (!page) page = 'home';
    return (
<div>
<ReactCSSTransitionGroup
transitionName="background"
transitionEnterTimeout={1000}
transitionLeaveTimeout={1000}
>
<BackgroundImage page={page} key={page} />
</ReactCSSTransitionGroup>
</div>
);
}
}
export default App;

this.props.location.pathname gives you the url (‘/about’ or ‘/’) and substr(1) lets you drop the ‘/’ in the beginning. If the string is empty you know it’s the home page you’re on. You can then pass the page as a prop to the BackgroundImage component.

So what does BackgroundImage look like? I’m glad you asked!

import React from 'react';
class BackgroundImage extends React.Component {
render() {
const urls = {
home: 'http://i.imgur.com/kJXRAZH.jpg',
about: 'http://i.imgur.com/TaA1gj9.png'
};
    const style = {
position: 'fixed',
top: 0,
zIndex: -1000,
backgroundColor: '#FFFEF4',
width: '100%'
};
   let src = urls[this.props.page];

return <img src={src} style={style} />;
}
}
export default BackgroundImage;

The component chooses an image url based on the page (passed as a prop) and renders an img element with the url as the source.

CSS Transitions

The following CSS classes let you slide the components in and out of the page — once again, we’re sticking to things we can animate cheaply.

.background-enter {
transform: translate(100%);
}
.background-enter.background-enter-active {
transform: translate(0%);
transition: transform 1000ms ease-in-out;
}
.background-leave {
transform: translate(0%);
}
.background-leave.background-leave-active {
transform: translate(-100%);
transition: transform 1000ms ease-in-out;
}

The component starts out beyond the right side of the page (since the width was set to 100%) and slides into the page just as the previous component slides out.

That’s about it! If you found this interesting, you might like to read more about using React Router, or about server rendering with React Router.

Doing something fun with React? Let me know!