Animating React Components with react-transition-group

Today I’ll be teaching you how to build a simple navigation bar with transitions in React. A Github repo is probably what most of you are looking for, so here you go! For those of you looking for my thought process while building this feature, follow the steps below, or take a look at my commit history.

First thing’s first: I used create-react-app (v1.4.3) to get started, removed most of the defaults (React icons, placeholder CSS, etc.) and imported a few fonts so I don’t have to look at the browser defaults. Your repo should look something like this at this point.

Let’s start creating our components. I like the convention of using a components/ folder inside of src/, but you can follow whatever convention you like. For this example, we care about two main components: our navigation bar and the remaining content. Create empty Navbar and Content components and load them into App.

There are a few smaller steps I’m going to skip for the sake of brevity, but I’d like to call them out:

  • Create Navbar and Content components and situate them on the page (not quite styling, but at least getting them in the correct place) — commit
  • Create placeholder links for Navbar and style — commit
  • Add placeholder content to Content to fill the page (You’ll notice I’m using a prop called dangerouslySetInnerHtml. This is for the sake of example and to keep the Content component uncluttered — here’s why you shouldn’t use it in production code.) — commit
  • Navbar needs to be opened and closed, so add state in order to do so — commit
  • Control that open/closed state in Navbar with a clickable icon — commit

All of the smaller steps above create most of our functionality — that is, having a page with content and a navigation bar that can be opened and closed. Here’s the code at this point:

Now we’re ready to add transitions to make the opening/closing of our navigation bar is a little smoother. To do this, I’m going to use react-transition-group (docs).

Upon clicking the navigation bar icon, there will be two transitions: 1) the width of the navigation bar will shrink/expand, and 2) the links in the navigation bar will fade out/in. Currently, the Navbar component controls the isOpen rendering logic (in renderNavbar()), but I’m going to pull this out into its own component called NavbarContent.

All I’ve done is removed the renderNavbar method and moved that logic into its own component called NavbarContent. Now our NavbarContent has some room to breathe so we can add transitions.

I’m going to use the Transition component from react-transition-group because it allows me to describe transition styles through JavaScript objects, but you can also use CSSTransition if you’d rather use CSS. Our Transition will need in (a boolean that toggles transition state) and timeout props, as well as an element that controls styling based on state.

There’s a lot going on here, so let’s break it down. There are two Transitions, both controlled by the same in and timeout props. The navbar and link styles only differ in the transition properties that they control — navbar changes width (to achieve the “slide in/out” effect) and the links change opacity (to fade in/out in concert with the navbar transition) at different points in state.

That’s it! Now go forward and animate components at your leisure.

Maddie is a software consultant on DevMynd’s software engineering team focusing on mobile apps and web development. She has been with the company since 2016.