Introduction to React Prop-Types

Introduction to React Prop-Types

Quick and easy runtime type checking for React props

Introduction

"Why won't this search-ahead open?!" you wonder to yourself while attempting to use your colleague's <CoolSearchAhead /> component. Finally, you break down and wade into the depths of the component. As it turns out, <CoolSearchAhead /> expects a prop called openOnClick, which tells the component to open when its parent input is clicked. You add the prop - <CoolSearchAhead openOnClick /> - and voila, it works!

Now, whether or not that prop should be required is a discussion for another time. In this moment, though, how could your frustration have been prevented? Enter prop-types.

What is PropTypes?

prop-types is a runtime type-checker for React props. This means that prop-types helps React validate that you are passing the necessary props to the components you interact with. If <CoolSearchAhead /> had used PropTypes, you would have known that you needed to pass in the openOnClick prop without even having to look at the SearchAhead component itself.

How do I use PropTypes?

Now we can get into the fun part - code! I'm going to use a more simplified component - let's just call it <Percentage /> - so that we don't get distracted from the usage of PropTypes... and because, honestly, I'm too lazy to build a fake search ahead.

Note: You can view the full source of this example at this CodeSandbox

For the sake of brevity, I'm going to assume that you have a React project of some kind up and running already. There are a ton of great tutorials online on how to get set up with a basic React project if you need a bit of guidance in that regard (which is totally okay!). This example project is based off of CodeSandbox's React template.

Let's start with the basics, we need to install prop-types! Just run npm install --save prop-types, and you're good to go. Or, if you're following along in CodeSandbox, add it as a dependency on the left rail under "Dependencies".

Now, we have our very basic App.js:

import "./styles.css";
import Percentage from './Percentage';

export default function App() {
  return (
    <div className="App">
      <p>This is your percentage:</p>
      <Percentage />
    </div>
  );
}

And Percentage.js:

import React from 'react';
const Percentage = (props) => {
  return (
    <div>{props.percent}%</div>
  )
}

export default Percentage;

So, as we can see, Percentage is a simple component that just takes in some props and displays a prop called percent with a % sign stuck onto it.

Now, let's say that you're a developer that's new to this team and you have no idea what props Percentage expects. Maybe you try <Percentage number={50} />, or <Percentage>50</Percentage>, or any infinite variations of names that you could come up with for a simple number. None of this works. So you finally dig into where the percentage is actually displayed and see that the component uses props.percent to display the number. That would have been great to know! So let's save the next developer some time and make it clear what <Percentage /> expects.

First, let's import prop-types:

import React from 'react';
import PropTypes from 'prop-types';

const Percentage = ({percent}) => {
  return (
    <div>{percent}%</div>
  )
}

export default Percentage;

Second, we need to attach PropTypes to our component. This is done by attaching the property propTypes to our const -

Percentage.propTypes = {

}

Now we're (already) almost done! There's just one more step -

Percentage.propTypes = {
    percent: PropTypes.number.isRequired
}

This tells PropTypes that the prop percent is of type number and it isRequired. The final code of <Percentage /> is now:

import React from 'react';
import PropTypes from 'prop-types';

const Percentage = ({percent}) => {
  return (
    <div>{percent}%</div>
  )
}

Percentage.propTypes = {
  percent: PropTypes.number.isRequired
}
export default Percentage;

Now open the console in CodeSandbox and refresh the "Browser" tab where your app is being displayed. You should see this error in the console:

Warning: Failed prop type: The prop `percent` is marked as required in `Percentage`, but its value is `undefined`.  
at Percentage ([https://n8qyr.csb.app/src/Percentage.js:19:3](https://n8qyr.csb.app/src/Percentage.js:19:3))  
at App

This is great! Now we immediately know the name of the prop that we have to pass in. So let's do that -

// App.js
...
    return (
        <div className="App">
          <p>This is your percentage:</p>
          <Percentage percent="25"/>
        </div>
      );
...

But wait! Now we get a new error:

Warning: Failed prop type: Invalid prop `percent` of type `string` supplied to `Percentage`, expected `number`.
    at Percentage (https://n8qyr.csb.app/src/Percentage.js:19:3)
    at App

This is because we passed the prop in as a string, not a number. So let's amend that -

// App.js
...
    return (
        <div className="App">
          <p>This is your percentage:</p>
          <Percentage percent={25}/>
        </div>
      );
...

Finally, our app is happy. You might have noticed when we put in the string that our percentage still happily showed up in the app - this is because these PropType errors are non-breaking. They're not intended to be a show-stopper for your app, they're simply an easy way for developers to get warnings about what props are expected (and what types they need to be) when using components.

Our percent prop is denoted as required via .isRequired. If you do not want this prop to be required, you can simply remove .isRequired and you won't get the console error when you leave the prop out completely. You will, however, still get a warning if you supply a string!

PropTypes has a lot of types so you'll always be able to find something that fits your needs. If you don't want to explicitly type-check though and essentially just want a way to document your props, you can simply mark your prop as type any and React will accept any type for the prop while still warning if a required one is missing.

Wrapping Up

Using PropTypes, we now have a quick and easy way to push our components to be self-documenting. Any developer that comes along and needs to use a component you built with PropTypes can now check out the PropTypes object and quickly understand what the component expects - or even just start using the component and see what errors pop up!

If you liked this article, have any questions, or want some additional content/clarifications to be added, please feel free to hit me up on Twitter!