Wireframes and Prototypes With React: Part 3

In our last post we made a generic Nav Bar, and saw how we can change up content quickly and easily. Today, we are going to finish up the header of our web app, and learn some more techniques to create other reusable components.

What’s in our Header?

From our amazing sketch, we see some sort of logo image, the navigation, probably a product name, and maybe a tag line. We also need to remember not to hire this designer again!

Make it quick

Once again, let’s start with plain old HTML, and then React-ify it. This is a way that I work very frequently: you get something down quick, then you can decide if it is worth re-using, and convert it to React in that case.

So here’s our first pass at the header:

<header>
    <h1>Contacrrr</h1>
    <h2>All those people and stuff!</h2>
    <img src="logo.png" alt="Contactrrr logo" />
    [ NAVIGATION GOES HERE! ]
</header>

ASIDE: stuffing your React components into normal old markup

If you want to mix your components with plain old markup, it’s quite easy to do. For our header, we would simply add a placeholder DIV with an Id:

<header>
   <h1>Contacrrr</h1>
   <h2>All those people and stuff!</h2>
   <img src="logo.png" alt="Contactrrr logo" />
   <div id="nav_placeholder"></div>
</header>

And then we can draw a React component into it like so:

 :::javascript
 // draw our NavBar into the placeholder
 React.render(<NavBar />, document.getElementById('nav_placeholder'));

This lets you use your components inside plain HTML while you are testing things out, or if the outer HTML is something you won’t be turning into a component.

Turn the header into a Component

Since we will probably be mocking up a lot of headers, let’s turn this into a component! Much like when we made our Nav Bar, we can wrap our HTML with React, making it the return of the render function. Since we want to reuse this, we will also replace the static text with props. Also note that we can include our NavBar component just like any other tag!

// our NavBar class here...

var SiteHeader = React.createClass({
    render: funtion () {
        return (
            <header>
                <h1>{ this.props.headerText }</h1>
                <h2>{ this.props.tagline }</h2>
                <img src="{ this.props.imgSrc }" alt="{ this.props.imgAlt }" />
                <NavBar navItems={ ['Home', 'About', 'Help', 'My Account'] } />
            </header>
        );
    }
});

And then we render the header into the document, making sure we pass in the props we need:

React.render(<SiteHeader 
                headerText="Conactrrr"
                tagline="All those people and stuff!"
                imgSrc="logo.png"
                imgAlt="Contactrrr logo" />,
                document.body);

Here is our lovely code in action at JSFiddle. Looks pretty good, however our spider-senses are tingling… Check out our NavBar. Our navItems are hard-coded in there, which means every SiteHeader will have those four items. Not at all what we want! Let’s fix that.

Passing Props Through

The good new is, this is simple as can be! We pass in a navItems prop on our header, and just pass it along to the NavBar:

 var SiteHeader = React.createClass({
    render: funtion () {
        return (
            <header>
                <h1>{ this.props.headerText }</h1>
                <h2>{ this.props.tagline }</h2>
                <img src="{ this.props.imgSrc }" alt="{ this.props.imgAlt }" />
                <NavBar navItems={ this.props.navItems } />
            </header>
        );
    }
});
// note the new navItems property below
React.render(<SiteHeader 
                headerText="Conactrrr"
                tagline="All those people and stuff!"
                navItems={  ['Home', 'About', 'Help', 'My Account'] }
                imgSrc="logo.png"
                imgAlt="Contactrrr logo" />,
                document.body);

Working example

Handling different configurations

Right now our header assumes we always have a headline, tag-line, and an image. Obviously this won’t be the case on every single thing we wireframe. So how do we handle optional elements? By using the power of if.

If you remove the tagline property in our last example, you’ll see it looks like it goes away when it’s rendered. This can be fine for text-only elements, but inspecting the page in your dev tools will show there’s still an empty H2 tag in there. If we have styles that force certain elements to be fixed heights, have margins, or whatever, we can have unwanted spaces or blocks displaying in our wireframe like in this example where I’ve removed the tagline property, but the CSS forces the empty element to take up space and show a background color.

We can take advantage of the fact that React won’t render things that have a value of false. By assigning elements we may not want to variables inside our function, we can choose to render them differently in the return like so:

var SiteHeader = React.createClass({
    render: function () {
        // start with no tagline element
        var taglineEl = false;
        // if we got passed a tagline prop...
        if (this.props.tagline) {
            // set the tagline element to an H2
            taglineEl = <h2>{ this.props.tagline }</h2>;
        }
        // now we render the taglineEl variable below, which will 
        // either be FALSE, and not draw anything at all, or an H2
        // tag if we got passed a tagline
        return (
            <header>
                <h1>{ this.props.headerText }</h1>
                { taglineEl }
                <img src={ this.props.imgSrc } alt={ this.props.imgAlt } />
                <NavBar navItems={ this.props.navItems } />
            </header>
        );
    }
});

To review what’s going on there: Above the return of our render function, we create a variable to hold our tagline element named taglineEl and set it to false by default. Next up, we check to see if we were passed a tagline prop. If so, we set taglineEl to be an H2 tag with our text in it. Down in the return of the function, we render the value of taglineEl, which not create any DOM element at all if we skip passing in tag line text, as seen here.

We can do this with all optional elements so we don’t render any empty DOM elements like so.

Other fancy IF tricks

By adding smarts to our components, we can quickly look at different states in our wireframes and prototypes. We may want to not show the H1 tag if we got an image, for example. By adding behavior properties (ones that we won’t draw, but help the component decide what to draw) we can again make our stuff more reusable by allowing one component to do lots and lots of things for us. In this case, we create a variable to hold the H1 tag, and then we use an if to check for two things: do we have an imageEl, and did we set the preferImageToH1 property? If both of those things are true (it wouldn’t makes sense to not show the H1 if we didn’t create an image!) then we set our variable to false, meaning we won’t render the H1:

var SiteHeader = React.createClass({
    render: function () {
        var taglineEl = false;
        if (this.props.tagline) {
            taglineEl = <h2>{ this.props.tagline }</h2>;
        }
        var imageEl = false;
        if (this.props.imgSrc) {
            imageEl = <img src={ this.props.imgSrc } alt={ this.props.imgAlt } />;
        }
        // make our usual H1 tag
        var h1El = <h1>{ this.props.headerText }</h1>;
        // if we have an image and want to show it instead of
        // the H1, set to false so we don't draw
        if (imageEl && this.props.preferImageToH1) {
            h1El = false;
        }
        return (
            <header>
                { h1El }
                { taglineEl }
                { imageEl }
                <NavBar navItems={ this.props.navItems } />
            </header>
        );
    }
});

Can you sense a JSfiddle example coming? I thought so.

Recap

So now we have a website header that is showcasing some of the neat things you can do with React. We can quickly change content without copying and pasting blocks of markup, we can have elements appear or vanish based on setting properties on the component, we see how we can nest components inside each other to make more complex things, and we’ve seen how to add logic to them to vary their behavior to make them even more generic. Not too shabby.

Next time: Housekeeping!

Before we move on to building the rest of our wireframe, we will take a little break and document our component so we can easily remember how to use it, and how to break up our components into separate javascript files. See you then!


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