Looping Over Child Components in React: Shotgun Episode 3

Photo: Midnight Cowboy — Brandon Bailey (CC-BY-2.0)

Shotgun is a new show that lets you ride shotgun with me while I tackle real programming challenges for real apps and libraries. The show is only available to members of EricElliottJS.com, but I’m journaling the adventures here.

Catch up:

Looping Over Child Components

My favorite thing about JSX is that it’s not a simple token replace template engine. It’s a compile-to-JS DSL specifically designed to make working with UI feel like writing HTML: only better.

One of the consequences of that design decision is that JSX doesn’t need any constructs for looping or conditionals like many template languages have. Instead, you use regular JavaScript to handle those things. In the latest episode I demonstrated how to use `Array.prototype.map()` to loop over list children and render them into a list. The result looks like this:

This means, for each item in the `cardList` array, return a corresponding `CardListItem`, which is another React component.

Here’s what `CardListItem()` looks like:

Note that each item in the list gets a `key` attribute. Each `key` must be unique. This is a requirement of React so that it has a way of uniquely identifying components, even if the props change and the list rendering is affected as a result. In other words, React uses those keys to remember which dynamic components are which and keep track of their state. Read “Why the Keys are Important” for more on what goes wrong when you omit them.

As you’ll see in the screencast, React warns when you forget the `keys`, as I almost always do in the first pass. (Thank you for all the helpful warnings, React team!)

Conditional Classes in JSX

You may be wondering what that `makeClasses()` call is all about:

It’s just a shortcut to make conditional classes a breeze. Here’s what the function looks like:

As you can see, it just takes a bunch of strings as parameters and returns a neatly filtered, space-separated string containing them. I use this trick in conjunction with ternary expressions, like the one you see above comparing `card.id` with `currentCardId`.

Factory Defaults for Test Data

Meanwhile, back in the unit tests, we were originally building props manually for each test, which looked something like this:

The problem with this approach is that as the component grows in complexity, required props might sneak in, which will force you to refactor all of your tests. Or, you can create a factory that looks like this:

I call this a defaults factory. Whatever you pass in as settings will override default properties. Everything else will use default values.

Now most of the `props` creation looks like this:

const props = makeProps();

To override a prop like `isCompleted`, you call it like this:

const props = makeProps({ isCompleted: true });

After refactoring all the tests to use the new factory, making the `cardList` a required parameter was no problem. Without the factory, we would have needed to add about 14 lines of code to each test. With the factory, we were actually able to make most of the tests smaller, not larger.

Another bonus: If we have to change up the structure of the props (a real possibility), we’ll need to update it in fewer places: only the tests which deal directly with the changed props.

If you’re a member, feel free to watch episode 3 now.

If you’re not yet a member, check out the teaser video, and join us. Shotgun is bundled with the Lifetime Access Pass, which gives you access to all our videos: a webcast series and course content covering topics like TDD, prototypal OO, functional programming, React, universal app development, ES6+ and more.

Learn JavaScript from Eric Elliott
Become a Lifetime Access Member:
Video experiences
Books & more…

Eric Elliott is the author of “Programming JavaScript Applications” (O’Reilly), and “Learn Universal JavaScript App Development with Node & React”. He has contributed to software experiences for Adobe Systems, Zumba Fitness, The Wall Street Journal, ESPN, BBC, and top recording artists including Usher, Frank Ocean, Metallica, and many more.

He spends most of his time in the San Francisco Bay Area with the most beautiful woman in the world.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.