Validating Props in React Components Using PropTypes

Validating Props in React Components Using PropTypes

Proptypes is a package that is used to check how data types flow between react components. It’s a runtime type checking that helps to validate props passed between react components.

Why are PropTypes Essential??

When building applications in React, errors often occur when passing props to components. These errors can lead to challenging bugs, especially in extensive projects with numerous components.

This is mostly because JavaScript functions are flexible, allowing them to accept varying data types without generating errors. This makes it challenging for developers to pinpoint exactly where a problem originates when something goes wrong.

For example; The Component.js file below has two props called name and bookTotal with data types of string and number respectively.

import React from "react";

 const Component = ({ name, bookTotal }) => {
   return (
     <div>
       <p>
         my name is {name} and I have {10 + bookTotal} books
       </p>
     </div>
  );
};

export default Component;

Subsequently, we need to introduce our 'Component' into the 'App.js' file to pass props and visualize our app.

Now, imagine we accidentally pass the 'bookTotal' prop as a string instead of a number, as shown in the following code snippet. Our app would behave unexpectedly, yet no error would appear in the console.

import "./App.css";
 import Component from "./Component";

 function App() {
   return (
     <div className="App">
       <Component name="Tomisin" booksTotal="20" />
     </div>
   );
}

export default App;

Below is what the result looks like;

prop1.png

In our Component.js file, we were trying to perform basic JavaScript addition by adding 10 and bookTotal prop together, which is meant to give us a total of 30 books, but now our result shows 1020 books, which is wrong.

JavaScript converted the number (10) into a string and proceeded to concatenate both strings without signalling an error that a number was anticipated instead of a string.

To avoid issues like the one above, it's crucial to diligently verify data types passed between components and confirm their alignment with expected types. To aid JavaScript in detecting such mistakes, PropTypes or TypeScript come in handy.

PropTypes and Typescript allow you to define and enforce the types of props being passed around your application. This helps to catch errors early on and makes it even easier to maintain and scale your codebase over time.

Using both methods is good, but in my opinion, your choice depends on how large your app is going to be or how you intend to use it. If you’re building a smaller app or a tool/library that will be used by others, using PropTypes might be the best option. And I’ll be talking more about PropTypes for this article.

Getting Started

To use PropTypes in react we need to install the dependency with the command below;

npm install prop-types –save

Then you import it into your project files like this;

import PropTypes from "prop-types";

Using PropTypes in React

Different validators in PropTypes can be used to check whether the data one received is valid.

Basic data types

This is the most basic way one can check if a prop is valid in react components. This is done by checking if the prop is one of the primitive data types in Javascript such as boolean, strings, numbers etc.

Here's a list of basic PropTypes for data type validation in JavaScript:

PropTypes.bool; //must be a Boolean
PropTypes.object; //must be an object
PropTypes.number; //must be a number
PropTypes.string; //must be a string
PropTypes.func; //must be a function
PropTypes.array; //must be an array
PropTypes.symbol; //must be a symbol
PropTypes.any; //Can be any property

Referencing the previous example, to prevent passing a string instead of a number, enforce PropTypes in your component like so:

import './App.css';
 import Component from './Component';
 import PropTypes from 'prop-types';

 function App() {
 …

 Component.propTypes = {
   name: PropTypes.string,
  bookTotal: PropTypes.number
}

export default App;

Using this PropType, we can make sure that “name” is always a string and “bookTotal” is always a number, and when we do otherwise just like we did earlier we will have the warning below in our console;

prop2.png

Required types

To ensure that a particular prop is mandatory or required for a particular component, we can specify the isRequired property;

function App() {
 …

 Component.propTypes = {
   name: PropTypes.string.isRequired,
   bookTotal: PropTypes.number.isRequired
 }

export default App;

Since we have specified that the two props are required, it is important to pass a value to both components. If we do not pass a value to bookTotal for example, we will receive the warning below in the console.

prop3.png

Multiple Types

Certain PropTypes only allow specific data types for props. They include:

  • PropTypes.oneOfType

  • PropTypes.oneOf

The 'PropTypes.oneOfType' method permits specifying acceptable data types for a prop using an array of valid PropTypes.

Consider the example below:

function App() {
   return (
     <div className="App">
       <Component name="Tomisin" bookTotal={4} />
     </div>
   );
 }

 Component.propTypes = {
  bookTotal: PropTypes.oneOfType([PropTypes.array, PropTypes.number]),
};

export default App;

In this case, 'bookTotal' can accept either a number or an array. Supplying a string, that doesn't match either type, triggers a warning.

prop4.png

For 'PropTypes.oneOf', this approach involves an array of permissible values rather than an array of PropTypes. This is mostly useful if you have a set of named constants for different states. For example, you can set two constant states to the bookState prop, this means the said prop can only be valid when you have only the two states in the example below.

function App() {
   return (
     <div className="App">
       <Component name="Tomisin" bookState="loadingbooks" />
     </div>
   );
 }

 Component.propTypes = {
  bookState: PropTypes.oneOf(["Readbook", "Unreadbook"]),
};

export default App;

Since "loadingbooks" isn't part of the accepted array of props, an error occurs;

prop5.png

Conclusion

We have seen how PropTypes can be very useful in validating data types in React. Exploring the use of propTypes can be a good way to catch errors and also flag props as important when building our applications.

Thanks for reading :)