Type Checking With React PropTypes
Tags: react, webdev, programming, javascript
Published: 2021-01-20 23:11:47

**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 writing `PropTypes.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.