Back

Introducing React PropTypes

Introducing React PropTypes

In React, PropTypes are a way to document the props that a component expects to receive. This can help you catch errors early in the development process and make it easier to understand the data types expected to be passed into a component and what the component is expected to return.

PropTypes are incredibly useful when it comes to fixing and finding bugs. In this tutorial, I will explore a crash course of everything you need to know about PropTypes and why they are still relevant even after the enhancement of TypeScript.

Basic PropTypes

In the context of the JavaScript library React, PropTypes are a way to check the data type of a component’s props (properties) at runtime. This can help catch bugs and ensure that your components are used correctly.

// App.js
import Component from './Component'
function App() {
 
  return (
    <div className="container">
      <Component name='Miracle' age='22'/>
    </div>
  )
}
export default App

And in our Component.js file:

// Component.js
function Component({name, age}) {
  return (
    <div>
        <h2>
        {`in 10 years ${name} will be ${age + 10}`}
        </h2>
    </div>
  )
}
export default Component

Here, I have a really basic React application set up. I have my App.js, and all its doing is rendering out our component and passing in the name “Miracle” and the age of 22, and in our component, we are rendering out a string that says in 10 years ${name} will be ${age + 10}, the image below resembles the result:

If you remember, we passed 22 as the age in our component, but we’re getting 2210 as Miracle’s age.

Knowing elementary mathematics, you would agree this is wrong, but what could be the cause?

This can’t necessarily be blamed on JavaScript as it has its language principles. And according to it, when a number is passed as a string, it simply treats both values - 10 and 22as strings and concatenates them, giving us "10" + "22" which is "1022". It will not do the maths we expect.

Hence, we mistakenly fell off the principle in that one. It was a gruesome mistake, but mistakes are inevitable during application development. In fact, the reason we need to debug most times is that we have made a mistake somehow.

If we take off the string this way:

// App.js
<Component name='Miracle' age={22}/>

We’ll have this fixed:

But then, this bug grows if you don’t see what it is outputting, which makes it most times so difficult to fix. Still, with PropTypes we can easily avoid this problem, and you will never have this issue again, and this is really why PropTypes is useful in application development.

Your application could also use TypeScript due to its static typing features. Still, sometimes the overhead of adding TypeScript is too much when all you want is some small type checking, like in a small application or a few parts of your application, and that’s where PropTypes excels.

We will go ahead and install the PropTypes package from NPM and see how we can fix this bug by utilizing the project.

Run this in your terminal.

npm i PropTypes

With that, it should speedily install, we can restart our application, and we have everything PropTypes has to offer.

To be able to use PropTypes to check basic types, we need to import it. Checking to see if a JavaScript primitive type, such as a boolean, text, object, etc., is the simplest approach to determine a prop’s type.

To do this, we will use the prop’s name as the key in the PropTypes object, with the exact PropType we are checking the value for that key.

// Component.js

import React from 'react'
import PropTypes from 'prop-types'
function Component({ name, age }) {
  return (
    <div>
      <h2>{`in 10 years ${name} will be ${age + 10}`}</h2>
    </div>
  )
  }
  Component.PropTypes = {
    name: PropTypes.string,
    age: PropTypes.number,
}
export default Component

The code above is essentially mapping the PropTypes of string to our name property and number to our age; let’s go back to our site:

Nothing has changed, but we open our console and notice an error.

One advantage TypeScript has is that it shows errors in your editor but TypeScript is an extra overhead, while with PropTypes you can just add and remove checks at will without any extra work.

If we remove the age prop in app.js we get no errors:

But we get a NaN (‘Not a Number’) error, which is incorrect. This is because by default all the PropTypes you define are optional. To make a PropType required, you need to make sure you specify the isRequired property:

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

When we save we have an error in our console:

We can as well check for other things, just to be clear we can go beyond just checking for strings and numbers, we can check for booleans, objects, function or string, these are all basic PropTypes:

Component.PropTypes = {
  name: PropTypes.string,
  age:  PropTypes.number,
        PropTypes.object,
        PropTypes.array
}

Session Replay for Developers

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — an open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

Advanced PropTypes

Advanced PropTypes allows you to specify more complex validation rules for your props. For example, you can use advanced PropTypes to ensure that a prop is a certain shape (i.e., an object with specific keys and values) or to check that a prop is an element of a specific type.

There are also a number of “advanced” prop types that you can use to validate more complex props. Some examples of advanced prop types include:

  • .oneOfType: checks that a prop is one of several possible types
  • .shape: checks that an object prop has a specific shape (i.e., that it has specific properties with specific types)
  • .instanceOf: checks that a prop is an instance of a specific class

You can use these advanced prop types to validate more complex props than a simple string, number, or boolean. For example, you might use the .shape validator to ensure that an object prop has a specific structure or the .instanceOf validator to ensure that a prop is an instance of a specific class.

Here is an example of using advanced PropTypes to check that a prop is an object with a specific shape:

MyComponent.PropTypes = {
  data: PropTypes.shape({
    id: PropTypes.number.isRequired,
    name: PropTypes.string.isRequired
  }).isRequired
}:

This will ensure that the data prop is an object with an id field that is a number, and a name field that is a string. If data is not an object with these properties, or if any of the required fields are missing or have the wrong data type, a warning will be logged to the console at runtime.

Comparing PropTypes and TypeScript

Although TypeScript might seem to be a superior option, both type-checking tools are crucial in their own right. The use of these checking tools depends on the user’s wants and project. This section is created to act as a guide for users so better decision-making facing their demands could be satisfied at ease.

Auto-completion and Syntax highlighting

Both programs feature plugins that offer auto-completion of component props data. But TypeScript’s highlighting features perform better than PropTypes. TypeScript Integrated Development environment tools like VS Code and Atom come with a ton of capabilities. When the necessary props’ data types are not provided, TypeScript appropriately indicates your components and goes ahead to offer suggestions for a solution.

Usability

PropTypes are plain and straightforward to get started with, and both JS and TS support them. TypeScript is more demanding in nature and compels developers to amend improper prop types or pass essential props in order to avoid failing the production build in addition complex types can be written more effectively in TypeScript since it offers a large variety of types.

Type-Checking

PropTypes performs type checking while the program is actively using the browser, while TypeScript type checking is performed when TypeScript code is compiled into JavaScript. This is an important piece to know because this influences how each tool should be used.

Type-Checking API data

This is where type checking, which was formerly explained, starts to make sense because the kind of data coming from an API cannot be checked with TypeScript. Such code cannot be successfully compiled since the content of such data can only be known during runtime. PropTypes, on the other hand, will issue warnings if the expected types are not met.

Developing a Component Library

If the production code is published to a package manager when developing a component library. TypeScript will be translated or compiled into JavaScript at compile time. This highlights the need for PropTypes once again, why? This is because users of your library cannot rely on your TypeScript type definitions for props. PropTypes are standard JavaScript code, therefore, when your library is used, validation will always be possible.

After viewing the comparison above, one might be perplexed as to why one should pick one over the other. Both tools are special and significant.

Personally, TypeScript will take precedence If I’m creating a tool that doesn’t need to be used by other developers. On the other hand, if my tool will be used by other developers, PropTypes would take precedence as it works with both JavaScript and TypeScript.

Conclusion

PropTypes are a fantastic method to give your application a first layer of defense. Even though it only detects mistakes at runtime, unlike TypeScript, which also detects issues during compilation, it is considerably simpler to set up and use than TypeScript. For further reading, you could go through the docs.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs and track user frustrations. Get complete visibility into your frontend with OpenReplay, the most advanced open-source session replay tool for developers.

OpenReplay