With PropTypes we can also check the inner structure of objects
Yesterday we learned how the PropTypes
library makes it easy for us to check the types of objects we pass to React components through the props.
For example, this code makes sure the object pokemons
is an array of objects:
Pokemons.propTypes = {
pokemons: PropTypes.arrayOf(PropTypes.object)
}
If we accidentally pass pokemons
as an array of other types, like an array of strings for example, we get a warning in the Javascript console and we can fix the error.
PropTypes
lets us go further, though. It lets us describe in detail the inner structure of an object, what is called the shape of an object. This makes our data validations more thorough and accurate.
The way we do this deep validation is by using the shape()
method of PropTypes
.
shape()
takes an object and validates the types inside the object.
Here's an example:
Pokemon.propTypes = {
pokemon: PropTypes.shape({
name: PropTypes.string,
id: PropTypes.number,
base_stamina: PropTypes.number,
base_defense: PropTypes.number
})
}
Here we validate that the pokemon
object has a name
of type string
, and id
, base_stamina
and base_defense
of type number
.
If the object we pass into our props has one of these properties wrong, we will get a warning, even though Javascript would be happy to accept a string in place of a number type.
Required properties
Sometimes we need to pass props objects that have some required properties and some optional ones.
PropTypes
helps us in this case as well by specifying which property is required and raising a warning if it's not present.
To perform this check we simply add isRequired
at the end of the property type, like so:
Pokemon.propTypes = {
pokemon: PropTypes.shape({
name: PropTypes.string,
id: PropTypes.number.isRequired // required property
})
}
We may not feel the need to use PropTypes
every single time, but when our project grows and becomes complex PropTypes
sure helps avoid bugs that could become difficult to track down.
Oldest comments (6)
Hi, nice article thanks.
I have one question: How should objects be marked as required.
Let's say I have an object:
id/name are required for the/any user.
For the component in question I require there is a user at all.
So wonder is the above definition correct, or should I also add
.isRequired
to the whole object? Making it:So tl;dr; are objects that have required properties, automatically required themselves? Or are the properties only required If an object is passed in?
Not sure if I understand your question correctly, but you would use PropTypes on a component, not an object.
So, if you have a
User
component, you would use PropTypes to enforce that theUser
component gets passed a prop namedid
and a prop namedname
, like this:On the other hand, if you have a
UserList
component, that has auser
prop that is an object, you would setid
andname
properties of theuser
object asisRequired
and that would give you a warning if the user is not passed in at all.Hope this makes sense.
Hey, no sorry what I meant was the user was an object, I should have denoted it with the shape type.
Although I wasn't sure if the user would automatically be required if all of its props were required, like this:
I figured out that in the above, those props are only required if the user is passed in at all. To also ensure a user is passed, not just a valid user I needed:
Shall leave it here in case it helps anyone else.
Thanks Sam, my eslint was throwing error and this fixed it!
Hi,
I'm unable to create PropType for following prop.
resolved by
PropTypes.arrayOf(
PropTypes.arrayOf(
PropTypes.oneOfType([
PropTypes.string.isRequired,
PropTypes.shape({
price: string,
color: string,
}),
])
)
)