loading...
Cover image for Honey, I Type Checked The Children

Honey, I Type Checked The Children

laurieontech profile image Laurie ・4 min read

Boilerplate Basics (4 Part Series)

1) Exports and Imports and Defaults, Oh My! 2) What's With All the Props Anyway? 3) Honey, I Type Checked The Children 4) Understanding ...mapGetters in Vuex

Join me as we continue on our quest to explain and understand boilerplate code!

Today we're going to dive into PropTypes in React. I was actually prompted to do this because of some template code that shows up when you use the gatsby new <project-name> command.

The first thing that jumped out at me was a code snippet that appears in layout.js.

Layout.propTypes = {
  children: PropTypes.node.isRequired,
}

What's interesting about this line of code is that it isn't technically Gatsby that is in charge here. This is actually React code (Gatsby is built on React), but it's included out of the box for Gatsby cli starter projects.

Catch your bugs!

Proptypes is a feature in React that helps validate the values being passed through props.

If you aren't familiar with props there is a bit of an overview in this post.


The idea is that PropTypes can catch mismatches in the type of data being passed from one component to another. For example, if msg is a String, but the component it's passed into is expecting a number. Even without Typescript or other type supported JavaScript extensions, React provides PropTypes as a built-in typechecking ability.

PropTypes in Action

PropTypes works at two levels. It ensures that the right type of data is passed into a particular component. It also checks to make sure a component is receiving the correct data type.

This post might help you understand components as a concept.

In the case of the code we started with, it is setting PropTypes for the Layout component. That is, defining validation for the props passed into Layout.

Layout.propTypes = {
     ...stuff goes here...
}

Where did the children come from?!

This is the Layout component the starter project comes with. Take a look at the props being passed into this component. It's passing a prop called children and referencing it in the body of the render function.

const Layout = ({ children }) => (
    render={data => (
      <>
        <Header siteTitle={data.site.siteMetadata.title} />
          <main>{children}</main>
          <footer/>
        </div>
      </>
    )}
)

Now let's look at an example of how the Layout component itself is used. We can find such an example in the NotFoundPage component generated by the starter project.

const NotFoundPage = () => (
  <Layout>
    <SEO title="404: Not found" />
    <h1>NOT FOUND</h1>
    <p>You just hit a route that doesn&#39;t exist... the sadness.</p>
  </Layout>
)

Well, that's kind of weird. At first glance Layout doesn't appear to be using props at all. Typically, props are passed as a key-value pair that appears in the open tag of a component. Something like this.

<Example msg="test" />

Then inside the Example component we'd pass in props and access the msg content. But Layout isn't doing that.

As it turns out, Layout is still using props, just in a different way. children is actually a special built-in prop. It refers to all of the content inside the Layout tag.

  <Layout>
//ALL OF THIS
    <SEO title="404: Not found" />
    <h1>NOT FOUND</h1>
    <p>You just hit a route that doesn't exist... the sadness.</p>
//TO THIS
  </Layout>
)

Everything between the Layout open and close tags is considered the children prop.

Let's Validate!

So back to our PropTypes validation. Now that we know what the children prop is we can start to understand how we're validating that content.

Layout.propTypes = {
  children: PropTypes.node.isRequired,
}

We can use Layout to wrap any number of things, but the only thing we care about is that we're wrapping something. We can't render a page with no information at all, or at least we don't want to. An empty layout is not what we're after. That's why we have isRequired.

We also want to give a somewhat nebulous definition of what that something may be. The node keyword is just saying, I've passed in something that's renderable. Whatever that is.

Don't Stop at Boilerplate

Keep in mind, this section of the template is ripe for change. As you define your Gatsby application you may want to enforce different standards. For example, you can limit the prop to have one parent element like so.

Layout.propTypes = {
  children: PropTypes.element.isRequired
};

Gatsby gives you this as a starting point to prompt you to use type enforcement and show you what it can do.

And that's it!

Now we understand what this PropTypes code snippet is doing to typecheck our Layout component. As an added bonus we're also more comfortable with the built-in children prop.

As always, too often we see throwaway lines of code inside frameworks and projects that we don't take the time to understand. I encourage you to curiously explore everything you see! It'll make you a better programmer.

Look out for more Boilerplate Basics coming soon!

Boilerplate Basics (4 Part Series)

1) Exports and Imports and Defaults, Oh My! 2) What's With All the Props Anyway? 3) Honey, I Type Checked The Children 4) Understanding ...mapGetters in Vuex

Posted on May 13 '19 by:

laurieontech profile

Laurie

@laurieontech

Software dev at Gatsby | DC techie | Conference speaker | egghead Instructor | TC39 Educators Committee | Girls Who Code Facilitator | Board game geek | @laurieontech on twitter

Discussion

markdown guide
 

A fun way to look at PropTypes :) Nicely written.

I see PropTypes increasingly replaced by static type checking, be it Flow or TypeScript. The advantage is that you don't have the overhead and warnings on live and still have the full type checking (and even more versatile one) in development.

What's your opinion on static vs. dynamic type checking?

 

I'm a big fan of static type checking! But writing something in Typescript isn't as simple as writing JS and adding types; at least not if you want to follow best practices. So dynamic type checking is a nice middle ground. Giving you some of those features without changing what you know.

 

Great! I'm loving this series! (And Epic title for this one haha)

 
 

I wonder how you come up with a title :D