Validate Custom React Component Props with PropTypes

Kent C. Dodds
InstructorKent C. Dodds

Share this video with your friends

Send Tweet
Published 5 years ago
Updated 2 years ago

In this lesson, we'll learn how you can use the prop-types module to validate a custom React component's props. We will start by building out a Proptypes object that throws an error if the prop passed is not of the required type. Then, we will import the React team's prop-types module and look at some of the useful utilities it provides like isRequired. Function components define Proptypes off of a property while Class components define Proptypes off of a static method.

Instructor: [00:00] When other people start using your components, sometimes they'll make mistakes when passing props. For example, here we're passing the value of true for first name which we're expecting to be a string in our component. We're not passing a last name prop at all. What is being rendered is not what we'd expect.

[00:16] To use PropTypes on a function component like say hello here, we'll say sayhello.proptypes is an object. To validate the first name prop, we'll add a first name key to this object. The value of this is a function which accepts props, prop name, and component name.

[00:36] Let's go ahead and say, if type of props at prop name is not equal to string, then we'll return a new error, "Hey, you should pass a string for prop name in component name, but you passed a type of props at prop name." With that, we'll see our error message being logged to the console here. Awesome.

[01:00] We need the same thing for the last name, so we'll pull this function out to an object that we'll call PropTypes and put it in a property called string. Then, we can set first name to proptypes.string, and last name and set that to proptypes.string as well. Super. Now, we're getting the error message for both of them.

[01:20] Because this and other PropTypes are so common, the react team has built a package called PropTypes which we can use just like the one we just built ourselves. I'll go ahead and add a new script tag up here at the top that pulls in PropTypes from unpackage.

[01:36] That's going to add a PropTypes global to our program. We can go ahead and remove our own implementation of PropTypes, and everything should work pretty much the same.

[01:46] There's one difference here now though. We're no longer getting the warning for the last name prop. The issue here is that all of the validators in the PropTypes module consider props to be optional by default, so if a prop is not provided, then the validator doesn't run. That's useful in some cases like where we provide a default value, like if were to add or unknown here for the last name.

[02:09] If we want it to specify a prop as required, we can simply .is required here for the first name and here for the last name. That will give us a new error indicating that this prop is required. For components declared as classes like this, we can continue to specify our PropTypes the same way, but it's more common to do this by making PropTypes a static property of the class like this. It works exactly the same way.

[02:34] Let's swap the development version of react to the production version. You'll notice now that our PropTypes validation is totally gone. This is because PropTypes is great for development, but it does slow things down a bit in an unnecessary way for production. The production version of react does not use PropTypes.

[02:53] This is great. If you want to improve things further, you can use babel-plugin-transform-react-remove-prop-types to automatically remove PropTypes from your code when you're building it for production, which will make things even faster for you.

[03:06] In review, to add PropTypes validation to your component, you add a PropTypes property to the function component or a static property to call PropTypes to the class component, like we're doing here.

[03:17] The keys of that object map to the props of your component. You then provide functions to validate the props. The PropTypes module has a bunch of validators available to you, and you can learn about those in the PropTypes documentation.

Tushar Chhibber
Tushar Chhibber
~ 5 years ago

When I use SayHello.propTypes = {
firstName(props, propName, componentName) { console.log('Hello') } }

This function is not getting called. Can anyone help me regarding this.

Tushar Chhibber
Tushar Chhibber
~ 5 years ago

Found the issue, I was using production react and react dom scripts. Silly me

ahmeddotkom
ahmeddotkom
~ 5 years ago

If propTypes are not supported, how can we validate props in production?

Kent C. Dodds
Kent C. Doddsinstructor
~ 5 years ago

You shouldn't validate props in production. They add a LOT of unnecessary work because they're intended for development-only. Why would you want to? Just make sure that you have no proptypes warnings in development and you shouldn't have any in production.

Jonathan Soifer
Jonathan Soifer
~ 4 years ago

@ahmeddotkom:

I believe the key is here:

make sure that you have no proptypes warnings in development and you shouldn't have any in production.

The development environment , when the software is running only in our own computers and not being used by our clients/customers/users is the appropriate place to test and check if there are any errors.

Using prop-types is the way we make sure those errors aren't happening. When we find them, we fix them. Once they are removed in the development environment they are removed once and for all, so no need to check again in the production environment .

ahmeddotkom
ahmeddotkom
~ 4 years ago

Yeah makes sense, thanks.

Mat Longinow
Mat Longinow
~ 4 years ago

I'm having trouble with the Error message. Mine is displaying this...

Warning: Failed prop type: Hey, you should pass a string for ${propName} in ${componentName} but you passed a ${typeof props[propName]}! in SayHello

I put my current code on a jsfiddle: https://jsfiddle.net/qms7d56x/

Any help would be appreciated!

Kent C. Dodds
Kent C. Doddsinstructor
~ 4 years ago

Looks like you're using a normal string when you should be using a template literal with back-tics (`).

Lokesh Sanapalli
Lokesh Sanapalli
~ 4 years ago

I am getting "PropTypes not defined" error, please help!!!

https://q5lop2ykj.codesandbox.io/

Tony Brown
Tony Brown
~ 4 years ago

I am getting "PropTypes not defined" error, please help!!!

https://q5lop2ykj.codesandbox.io/ @Lokesh This link is dead

Daniel
Daniel
~ 4 years ago

Why does your implementation of 'propTypes' throw an Error when you actually never call it? Seems like more of a JS thing then React (yea, I know React is just JS haha).

Kent C. Dodds
Kent C. Doddsinstructor
~ 4 years ago

React will call it for us (in development mode)!

mdondorf-anynines
mdondorf-anynines
~ 4 years ago

Hey Kent, in your first transcript code example, you're missing a comma:

reactDOM.render( <SayHello firstName={true} />, document.getElementById('root') )

mdondorf-anynines
mdondorf-anynines
~ 4 years ago

Hey Kent, in your first transcript code example, you're missing a comma:

reactDOM.render( <SayHello firstName={true} />, document.getElementById('root') )

Kent C. Dodds
Kent C. Doddsinstructor
~ 4 years ago

Thanks! Will fix.

celipas
celipas
~ 4 years ago

Hi! reactDOM is not defined. I believe it should be ReactDOM is not defined

Sam Huang
Sam Huang
~ 4 years ago

Hello Kent, (following up with @celipas) In your first code snippet, you had

reactDOM.redner() instead of ReactDOM.render() the R should be capitalize

Modesta Naciute
Modesta Naciute
~ 3 years ago

Just an FYI, in transcript, thecode under <code>class SayHello extends React.Component</code> should be <code> Hello {firstName} {lastName}! </code>

Andy Elion
Andy Elion
~ 3 years ago

Script for prop-types should be

<script src="https://unpkg.com/prop-types@15.6.0/prop-types.js"></script>
Stacie
Stacie
~ 3 years ago

The unpkg script wasn't working for me. I changed to this source and it works: https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.js

Keith Price
Keith Price
~ 3 years ago

It would be helpful if you didn't use features in your modules unless you also explain them. In this case, you used back-ticks and just whizzed by it without mentioning it at all. That makes it really hard to follow when you're a beginner.

~ 2 years ago

Update paths to point to development version:

<script src="https://unpkg.com/react@16.3.1/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.3.1/umd/react-dom.development.js"></script>

When I use SayHello.propTypes = {
firstName(props, propName, componentName) { console.log('Hello') } }

This function is not getting called. Can anyone help me regarding this.