Wireframes and Prototypes With React: Part 2

In part two, we’ll create our very first reusable wireframe component and show off a few of the benefits of using React. Make another copy of your template.html file, name it navBar.html, and open it up in your editor of choice. (If you missed it, you can find the first part of the series here.)

As a reminder, we are going to be wireframing / prototyping Contactrrr, a hot new web app for managing your address book:

Picture of a sketch of a made up product

Conactrrr, the best thing ever

Start at the top: the Nav Bar

We will start with the navigation bar because it will show some of the power of using React versus plain HTML quickly. First let’s make the bar as normal markup. Inside the PUT STUFF HERE comments, add this:

<nav role="navigation">
    <ul>
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">My Account</a></li>
        <li><a href="#">Contact</a></li>
    </ul>
</nav>

Awesome. Take a look, and make sure you have a list of links. If you are feeling motivated, you can style them with CSS!

Convert to React

Now, let’s turn this into a React component. Take what you have already and wrap it with a script tag and the React component making code, and render it:

<script type="text/jsx">
    // creates a NavBar component
    var NavBar = React.createClass({ 
        render: function () {
            return (
                <nav role="navigation">
                    <ul>
                        <li><a href="#">Home</a></li>
                        <li><a href="#">About</a></li>
                        <li><a href="#">My Account</a></li>
                        <li><a href="#">Contact</a></li>
                    </ul>
                </nav>
            );
        }
    });
    // draw our NavBar into the body
    React.render(<NavBar />, document.body);
</script>

Don’t forget the type="text/jsx"!

Reload your page, and you should see exactly what you saw before. Here’s what we’ve done in a JSFiddle with some ugly styling applied.

So far, all we’ve done is make more work for ourselves, but let us make the move to React pay off quickly!

Make it Generic so We can Reuse

Having a nav bar with a fixed set of items is helpful if every site we mock up will always be exactly the same, but that’s not going to be the case! Our NavBar shouldn’t render a specific navigation menu: it should act a generic navigation rendering machine that we can pass a list of nav items into to get a menu out of it.

Props

Every React component has props (short for properties; not to be confused with props of the “mad” variety, which one might give their component for doing an admirable job) that can be set. Remember our HiThere component? Here it is again, but this time with the text passed in:

var HiThere = React.createClass({
    render: function () {
        return (
            // we ask for the value of 'headerText' prop here
            <h1>{ this.props.headerText }</h1>
        );
    }
});
// set the value for headerText when we want to draw:
React.render(<HiThere headerText="Hello World"/>, document.body);

We can use props to change what our NavBar displays by passing in our links when we draw the component. Our render function will loop over the list and make an LI (or whatever we want) for each one. We’ll use a map function do do this. What the heck is a map, you ask? Let us take a quick side trip find out!

Maps

This is the most complicated bit of code you’ll have to learn through this series, and even this is pretty easy, so don’t be worried!

A map in our case takes a list (array), does “something” to each element, and makes a new array out of it. An example is probably more clear:

// Make an array of some letters
var originalList = ['a','b','c','d'];

// Create a new array by mapping over the original.
// The function will get run once for each element of originalList
var newList = originalList.map(function (letter) {
    // 'letter' is the element of originalList we are working on at the moment
    // for some reason, we will tack a Z onto that letter
    var withZ = letter + "Z";
    // Whatever we return will be added onto the end of newList
    return withZ;
});

// newList is now: ['aZ','bZ','cZ','dZ']

There’s a lot going on in those few lines, so let us recap what went on there:

  1. We made an array
  2. We created a new array by calling map on the original array.
  3. The map function was called for each element of originalList.
  4. Each iteration of the map function was passed an element of our original list.
  5. The function took whatever letter we were on at the moment and stuck a ‘Z’ onto it.
  6. We returned that “withZ” string and map added it onto the end of newList
  7. After map is done running, newList is a new array full of our “withZ” strings, and originalList is untouched.

And that’s map in JavaScript!

Mapping our Nav

We can use that crazy map thing to make our NavBar into a reusable component by setting a list of nav items as a prop and generating the LIs dynamically. We’ll do this in two steps so it is a little easier to follow along.

Step 1: Move our static list to a map

First, we will draw our four fixed navigation elements via a map function:

// creates a NavBar component
var NavBar = React.createClass({ 
    render: function () {
        // move our four titles into an array
        var navItems = ['Home', 'About', 'My Account', 'Contact'];

        // use MAP to create four LI elements
        var navElements = navItems.map( function(title) {
            // create an LI
            var navItem = <li><a href="#">{ title }</a></li>
            // return it so it is added to the navElements List
            return navItem;
        });
        // navElements now has four LIs in it.

        // we now draw our 'navElements' inside the UL
        return (
            <nav role="navigation">
                <ul>
                    { navElements }
                </ul>
            </nav>
        );
    }
});

Super duper! Reload, and once again, you should see nothing different. Once again, here it is in a JSFiddle for you. We’ll make one more change and we will have our first complete, reusable wire-framing component.

Step 2: Switch to props

Right now, our list of nav items lives inside the component, which means it can still only draw one NavBar. We will fix that by changing where we get our list from the render function to a prop we can set when we render:

// creates a NavBar component
var NavBar = React.createClass({ 
    render: function () {

        // use MAP to create LI elements from our navItems prop
        var navElements = this.props.navItems.map( function(title) {
            var navItem = <li><a href="#">{ title }</a></li>
            return navItem;
        });

        // we now draw our 'navElements' inside the UL
        return (
            <nav role="navigation">
                <ul>
                    { navElements }
                </ul>
            </nav>
        );
    }
});

// draw our NavBar into the body, passing in the navItems
React.render(<NavBar navItems={ ['How', 'Now', 'Brown', 'Cow'] } />, document.body);

When we reload now, we should get the amazing experience of actually seeing something new! Obligatory JSfiddle here.

Show me the Useful

Now that we have something reusable, what does that get us? Let us count the ways:

How does it look with…” testing.

Wireframes and prototypes can fall into the trap of adding just enough content to make them look perfect. We can quickly and easily look at how our styled nav bar looks with various content configurations:

<script type="text/jsx">
    // our NavBar class here...
</script>

<div id="nav_one"></div>
<div id="nav_two"></div>
<div id="nav_three"></div>

<script type="text/jsx">
    React.render(
        <NavBar navItems={ ['About', 'Contact', 'Work'] } />, 
        document.getElementById('nav_one')
    );

    React.render(
        <NavBar navItems={ ['About', 'Contact', 'Work', 'Support', 'Blog', 'Home', 'People'] } />, 
        document.getElementById('nav_two')
    );

    React.render(
        <NavBar navItems={ ['Onomonpea', 'Lethargic', 'Discombobulaed', 'Gewurztraminer'] } />, 
        document.getElementById('nav_three')
    );
</script>

We can plop down as many NavBar components as we want, and by tweaking that one navItems list, we can see how they behave when things change very quickly. JSFiddle

Side by Side Look and Feel Checks

Since we can easily repeat a component, throw a few on the same page and tweak CSS rules based on the parent container so you can look at variations side by side:

<script type="text/jsx">
    // our NavBar class here...
</script>

<style>
    #nav_one li { /* rules for version 1 */ }
    #nav_two li { /* rules for version 2 */ }
    #nav_three li { /* rules for version 3 */ }
</style>

<div id="nav_one"></div>
<div id="nav_two"></div>
<div id="nav_three"></div>

<script type="text/jsx">
    // define a common set of items...
    var navItems = ['About', 'Contact', 'Work', 'Support', 'Blog'];

    React.render(
        <NavBar navItems={ navItems } />, document.getElementById('nav_one')
    );

    React.render(
        <NavBar navItems={ navItems } />, document.getElementById('nav_two')
    );

    React.render(
        <NavBar navItems={ navItems } />, document.getElementById('nav_three')
    );
</script>

By rendering the same NavBar many times into containers with different IDs, we can look at multiple styles together, and use our browser dev tools to change one or more while keeping the “baseline” to compare with. (JSFiddle)

Heck you could even define a component just for this purpose that cranked out X number of NavBars for you:

<NavBarFactory navItems={ navItems } navBarCount="10" />

Oh look, here’s something just like that!

Less Markup!

Right now we only have a single component, but that one NavBar tag takes the place of a whole bunch of others (a nav, ul, and an li for every item) so our wireframe code is really easy to read. As the size of the sites / apps we build grow, this can be a life-saver.

Up Next

Part three is up, where we will finish up the whole header section, learn about composition, and show how to make our components even more reusable!


Thanks for reading, and until next time, happy coding! I would love to hear feedback or answer any questions via twitter: @veddermatic or by email

back to top