Welcome back one and all! I’m excited to see you here and eager for you to take your next step on your CodeQuest towards the grok of React.js. It’s been a long road so far, we’ve covered a lot of ground and you’ve learned a lot of new code spells that will see you weaving all sorts of web development magic.

Along the way you may have even picked up a couple of magical artifacts. But now that we’re here, 10 tutorials in, perhaps it’s time to add some polish to all these new skills you have. All technique and no flourish makes for a boring demonstration after all! This week we’re going to take the sample application we’ve been building and add a little style by utilising the ReactCSSTransitionGroups plugin in our application.

Want to follow along but haven’t done the previous tutorials? Clone down this repo to give you a starting point. Once you’ve cloned it down run the command npm install in the root of the project and you’ll be good to go!

 

Who? What? Where?

Let’s talk about what ReactCSSTransitionGroups is/are. ReactCSSTransitionGroups is a plugin that you can import into your react components that will allow you to animate the mounting and unmounting of component.

What means techinically is that when React is mounting and unmounting your components it will add a css class to the DOM elements it’s creating and removing. You can specify what these classes should be called thus allowing you use CSS3 animations on these entering and exiting components.

This can be quite useful, for example, when you want to add a little bit of flair to the entrance and exit of elements that get created or removed from a list on screen. Another use case is to make the appearance of modal dialog boxes a bit more pleasant.

 

Adding another wolf to your pack

Let’s not waste anymore time talking about it, let’s just jump in! To begin with we’ll need to pull in the react-addons-css-transition-group package. For convenience, we’ll also save it into the dependencies for our solution.

I have spent some time previous tutorials explaining what all that means so I’ll point you back to them for further explanation. For now I’ll just give you the command to pull in what you need:

npm i react-addons-css-transition-group -S

 

Teach your list items to strut

If you’ve already used the npm start command on the project and had a click around you’ll notice that currently you can add an item to the bottom of the list by hitting the big green plus button at the bottom of the list. But when this item is added I think you’ll agree that the item comes in rather abruptly and it gives a sort of janky stuttering feeling.

This is where we can use ReactCSSTransitionGroups. Go ahead and open up the src/scrollTemplateList/containers/ScrollTemplateList.jsx file and make the highlighted changes to the markup in the render function of that component:

<div className="scroll-template-list-resting">
<div className="grid-header grid-row">
<div className="grid-cell">Their Name</div>
<div className="grid-cell">Your Name</div>
<div className="end-of-row-header-spacer" />
</div>
<ReactCSSTransitionGroup
transitionName="scroll-template-list-items"
transitionEnterTimeout={500}
transitionEnter
transitionLeaveTimeout={500}
transitionLeave
>
{
this.state.data.map((d, idx) =>
(
<ScrollTemplateListItem
key={idx}
formData={d}
index={idx}
rowDisplayingAdvancedDetail={this.state.rowDisplayingAdvancedDetail}
handleToggleDetailClick={this.handleToggleDetailClick}
removeItem={this.handleRemoveClick}
createNewItemForMessageBody={this.createNewEntryForMulti}
changeSingleValue={this.changeSingleValue}
changeMultiValue={this.changeMultiValue}
removeItemFromMessageBody={this.removeEntryForMulti}
/>
)
)
}
</ReactCSSTransitionGroup>
<button
className="scroll-template-list-add-button scroll-template-list-item
glyphicon
glyphicon-plus btn btn-success"
onClick={this.handleAddClick}
/>
</div>

You’ll see that the only change we’ve made here is to wrap the mapping of the this.state.data array with a ReactCSSTransitionGroup component. By doing this we are passing the resulting mapped components into the ReactCSSTransitionGroup component as children. This then allow the ReactCSSTransitionGroup to monitor when children are added to or removed from the mapped array and take action as necessary.

You’ll also notice that we’ve provided the ReactCSSTransitionGroup component a number of props which it uses for configuration, let’s take a quick walk through them now.

transitionName

This unimaginatively named prop is the name of your transition. It is used to prefix the css classes that are used by your transition. Knowing this prefix you can then write css selectors that you can use to animate the different states of the transition.

transitionEnter

If this prop is set then we are telling ReactCSSTransitionGroup that we want to animate it’s children when they are added to the list.

transitionEnterTimeout

As you’ll see in a moment we’ll be using a CSS3 animations that will take a little time to complete. In this prop we are telling the render function how long we plan to have these animations going for. In this way we are able to tell ReactCSSTransitionGroup when to remove the css classes that it uses to specify that a new child is entering.

transitionLeave

You guessed it! This is telling ReactCSSTransitionGroup that we want to animate children of the component when they are removed from the list.

transitionLeaveTimeout

Let’s save some pixels and say that you already know what this prop is for.

One last thing you’ll need to do is add an import at the top of the file to bring in the ReactCSSTransitionGroup component from the plugin we installed earlier:

import ReactCSSTransitionGroup from 'react-addons-css-transition-group';

Now all that is left to do is to define our animations. For this I’ve put all the css in the src/scrollTemplateList/styles/scrollTemplateListItem.css. We just need to add the code below:

.scroll-template-list-items-enter {
opacity: 0;
height: 0;
margin: 0 20px;
padding: 0 5px;
}
.scroll-template-list-items-enter.scroll-template-list-items-enter-active {
opacity: 1;
margin: 5px 20px;
height: auto;
padding: 5px;
transition: opacity 0.5s ease-in, height 0.1s linear, margin 0.1s linear, padding 0.1s linear;
}
.scroll-template-list-items-leave {
opacity: 1;
margin: 5px 20px;
height: auto;
padding: 5px;
}
.scroll-template-list-items-leave.scroll-template-list-items-leave-active {
opacity: 0;
height: 0;
margin: 0 20px;
padding: 0 5px;
transition: opacity 0.3s linear, height 0.3s ease-out, margin 0.3s ease-out, padding 0.3s ease-out;
}

In terms of CSS there isn’t anything spectacularly complicated or anything that can’t be explained by a short google so I’ll assume that hasn’t blown your mind and get on to the ReactCSSTransitionGroup specific stuff that’s going on here.

The first thing to notice is that all of our CSS class names begin with “scroll-template-list-items”. It isn’t a coincidence, remember this is what we defined as the transitionName in the ReactCSSTransitionGroup component. For each of the class names you’ll see that there is a “-enter” or “-leave” for each of the appropriate transitions that we want to animate. Further to this you’ll see an extra class defined for each of the enter and leave classes that append a “-active” to the class name.

So what does this code give us and why? To deeply understand this we need to first understand what actually happens when a child is added to the list of children under the ReactCSSTransitionGroup.

When the child is added and an appropriate DOM node is created React adds two classes to the DOM node scroll-template-list-items-enter and then scroll-template-list-items-enter-active. It leaves both of these classes on the DOM node for the length of the timeout configured by the prop on the ReactCSSTransitionGroup component. Then once the timeout has expired both the classes are removed.

Based on this behaviour I’m sure it’s easier to understand how all this works. The scroll-template-list-items-enter css selector in the code above defines a starting point for the animation and the .scroll-template-list-items-enter.scroll-template-list-items-enter-active selector defines the end state along with the transition it should animate between the two states.

Having understood all that it goes without saying that for the leave functionality the opposite of everything I’ve said above is true.

If you now take another look at your creation (using npm start) you’ll see that when you add a new row to our list that it has a nice little grow transition and and equally pretty transition when you remove a row.

Whilst we’re in the application why don’t you try clicking on one of the rows to expand out it’s detail. Within you’ll see a component which we’ve dubbed a MultiTextInput. This component allows you to add and remove rows in a similar fashion to the ScrollTemplateList.

For completeness it would be great to add transitions to the adding and removal of these input elements. These changes are more or less identical to the one’s we’ve done in the ScrollTemplateListItem, why don’t you give making these changes a try yourself? You can always use the CodeQuest git hub repository if you get stuck and need a hint.

 

Peek-a-boo!

One other piece of functionality provided by ReactCSSTransitionGroups is the appear functionality. This works in a similar way to the enter functionality except that where as enter animates the entrance of children that are being added to already mounted components, the appear functionality animates the children when the parent ReactCSSTransitionGroup is first mounted. This makes the appear functionality most useful for things like dialog boxes or when elements of a page are first being loaded in general.

Let’s use the appear functionality to make our scroll list look cool when it first appears on the screen. To do this we just need to wrap the entire rendered content with in the ScrollTemplateList component in another ReactCSSTransitionGroup like this:

render() {
return (
<ReactCSSTransitionGroup
transitionName="scroll-template-list"
transitionAppear
transitionAppearTimeout={500}
transitionEnter={false}
transitionLeave={false}
>
<div className="scroll-template-list-resting">
<div className="grid-header grid-row">
<div className="grid-cell">Their Name</div>
<div className="grid-cell">Your Name</div>
<div className="end-of-row-header-spacer" />
</div>
<ReactCSSTransitionGroup
transitionName="scroll-template-list-items"
transitionEnterTimeout={500}
transitionEnter
transitionLeaveTimeout={500}
transitionLeave
>
{
this.state.data.map((d, idx) =>
(
<ScrollTemplateListItem
key={idx}
formData={d}
index={idx}
rowDisplayingAdvancedDetail={this.state.rowDisplayingAdvancedDetail}
handleToggleDetailClick={this.handleToggleDetailClick}
removeItem={this.handleRemoveClick}
createNewItemForMessageBody={this.createNewEntryForMulti}
changeSingleValue={this.changeSingleValue}
changeMultiValue={this.changeMultiValue}
removeItemFromMessageBody={this.removeEntryForMulti}
/>
)
)
}
</ReactCSSTransitionGroup>
<button
className="scroll-template-list-add-button scroll-template-list-item
glyphicon
glyphicon-plus btn btn-success"
onClick={this.handleAddClick}
/>
</div>
</ReactCSSTransitionGroup>
);

You can see on the props of the new ReactCSSTransitionGroup component that we still specify a transition name. We also still use the transitionEnter and transitionLeave props but this time we pass them the value false to tell the component that we aren’t going to be using these transitions.

The new prop here is the transitionAppear property. We provide this property when we want to use the appear functionality and we should also give it a timeout. These two props act identically to their transitionEnter and transitionLeave counterparts.

You may have already guessed at what the css below was going to look like. We’re going to add this to the bottom of the scrollTemplateList.css file:

.scroll-template-list-appear {
margin: 5% 10%;
height: 0;
opacity: 0;
}
.scroll-template-list-appear.scroll-template-list-appear-active {
margin: 10%;
opacity: 1;
height: auto;
transition: margin 0.5s linear, height 0.5s linear, opacity 1s ease-in;
}

 

Hey Presto!

And there you have it, you should now have an application that responds to your interactions in a much nicer way. This plugin for your React solutions can really help to create some nice experiences quiet easily.

Whilst we covered the basics of what the ReactCSSTranisitonGroup component can do for you in this article if you start using ReactCSSTransitionGroups in the wild and find that you have problems  or there is something specific you are wanting it do then it might be worth heading over the React docs page for it to read all about the gotchas and more in depth configuration available on the component.

Well, that’s all for this week, I hope you enjoyed the post and if you have any questions or comments about this weeks tutorial then please don’t hesitate to drop a comment on this post or get on to me direct using any of the social media’s which you can find at the top of the page.