Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62
Subscribe to my email list now at http://jauyeung.net/subscribe/
React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.
In this article, we’ll look at how to valid prop data types by using PropTypes
.
Type Checking With PropType
As our code grows, we can catch a lot of bugs with type checking.
React has built-in type checking abilities for props.
We can add prop type checks as follows:
import React from "react";
import ReactDOM from "react-dom";
import PropTypes from "prop-types";
class Greeting extends React.Component {
render() {
return <p>Hello, {this.props.name}</p>;
}
}
Greeting.propTypes = {
name: PropTypes.string
};
class App extends React.Component {
render() {
return <Greeting name="Jane" />;
}
}
In the code above, we have:
Greeting.propTypes = {
name: PropTypes.string
};
to check that the name
prop passed in is a string.
In addition to strings, it has many other kinds of validations that can be used to make sure that data received is valid.
When an invalid value is provided for a prop, a warning will be shown in the JavaScript console.
Prop type checks are only run in development mode for performance reasons.
PropTypes
In addition to strings, there’re many more prop types available. They’re the following:
-
PropTypes.array
— checks for arrays -
PropTypes.bool
— checks for boolean -
PropTypes.func
— checks for functions -
PropTypes.number
— checks for number -
PropTypes.object
— checks for object -
PropTypes.string
— checks for string -
PropTypes.symbol
— checks for symbol -
PropTypes.node
— checks for anything that can be rendered -
PropTypes.element
— checks for a React element -
PropTypes.elementType
— checks for a React element type (e.g.Component
) -
PropTypes.instanceOf(Foo)
— checks for instance of a class, in this case,Foo
-
PropTypes.oneOf([‘foo’, ‘bar’])
— checks for one of the values in the array -
PropTypes.oneOfType([PropTypes.string, PropTypes.number])
— checks for one of the types in the array -
PropTypes.arrayOf(PropTypes.number)
— checks for an array of the given type -
PropTypes.shape({color: PropTypes.string, fontSize: PropTypes.number }
— checks for an object with these properties and types of values -
PropTypes.exact({ name: PropTypes.string, quantity: PropTypes.number })
— checks for an object with these properties and types of values with warnings on extra properties -
isRequired
— set a prop as being required, e.g. we can use is by writingPropTypes.func.isRequired
to make a prop that takes a function required.
We can also set our own prop validation function as follows:
class Greeting extends React.Component {
render() {
return <p>Hello, {this.props.name}</p>;
}
}
Greeting.propTypes = {
name(props, propName, componentName) {
if (!["Jane", "Joe"].includes(props[propName])) {
throw new Error("Invalid name");
}
}
};
class App extends React.Component {
render() {
return <Greeting name="Foo" />;
}
}
In the code above, we have:
Greeting.propTypes = {
name(props, propName, componentName) {
if (!["Jane", "Joe"].includes(props[propName])) {
throw new Error("Invalid name");
}
}
};
which has the name
function where we can check the name
prop to see if it’s set to 'Jane'
or 'Joe'
.
If it’s not, like the example above, we’ll get the warning:
Warning: Failed prop type: Invalid name
in the JavaScript console.
Requiring Single Child
We can specify that only a single child can be passed to a component as children.
To do this, we write:
class Greeting extends React.Component {
render() {
return <p>Hello, {this.props.children}</p>;
}
}
Greeting.propTypes = {
children: PropTypes.element.isRequired
};
class App extends React.Component {
render() {
return <Greeting>Jane</Greeting>;
}
}
In the code above, we specified that children
has the type PropTypes.element.isRequired
, which means that we check if only one element is passed in.
Default Prop Values
We can also set default values for props.
For instance, we can write:
class Greeting extends React.Component {
render() {
return <p>Hello, {this.props.name}</p>;
}
}
Greeting.defaultProps = {
name: "Jane"
};
class App extends React.Component {
render() {
return <Greeting />;
}
}
In the code above, we have the defaultProps
property set for Greeting
to set the default props.
Since we didn’t pass any value for the name
prop to Greeting
, React will set the name
prop to 'Jane'
by default, so we get Hello, Jane.
If we change 'Jane'
to 'Joe'
, then we get Hello, Joe instead.
Conclusion
We can use prop types to check the types for our props. This prevents us from passing in data that we don’t want, preventing potential bugs.
Prop types can check for many types, including any JavaScript type, like numbers, objects, and symbols.
It can also check the structure of objects and arrays, and also checks if specific values are passed in.
In addition, we can make our own validator function to check what they’re and throw an error to reject invalid values.
We can add prop type check for children
to validate what’s passed in between tags.
Also, we can set a default value for props, by setting a value for it in the defaultProps
object.
Finally, we can use isRequired
to check for if a prop value is passed in.