DEV Community

Cover image for Check for extraneous props in React (and save hours of debugging)
Vincent Voyer
Vincent Voyer

Posted on • Edited on

Check for extraneous props in React (and save hours of debugging)

Photo by Nicole De Khors from Burst

2022 update: TypeScript provides this feature by default when buidling components in .tsx files. So if you're reading this, and not yet using TypeScript, not may be a good time to give it a try (no more proptypes, no more weird setups).


I have been doing more and more React recently and been bit by a nasty habit of me: passing down unknown props to my React components and wondering why it's not working for 10 minutes (OR MORE 😀). If you've already done some React I am sure you'll understand what I mean.

A debugging story

Let's start with an example.

On Monday, I create a new Input component:

// Input.js
import React from "react";
import PropTypes from "prop-types";

export default function Input({
  label,
  type
}) {
  return (<label>{label} <input type={type} /></label>)
}

Input.propTypes = {
  label: PropTypes.string,
  type: PropTypes.string
};
Enter fullscreen mode Exit fullscreen mode

I use it this way: <Input type="text" label="name" />. All good here's my little input with a label.

On Tuesday, after some heavy code afternoon, I decide that it should be labelText instead of label (naming is hard). Fine, let's change the calling code: <Input type="text" labelText="name" /> and now let's change the implement... "HEY WANNA GRAB A COFFEE?" says a friend? Sure sure ok...

⏳ 30 minutes later, I go back to coding. "Ok let's see this page I was working on ... Hmm, why is this not working? Why is my label blank?"

There's no error in console:

Alt Text

And:

Alt Text

"AH! Yes, that prop, it's not the right name, let's fix it... πŸ˜–"

It's easy to spot the mistake if you're reading this right now, but in real life, this happens to me all the time: passing down unknown props to a React component will not trigger a warning or error by default. And this is annoying to the point that I needed a solution.

Let's see how we can solve that.

eslint-plugin-react

I already use eslint-plugin-react and highly recommend it. Its recommended setting will activate the prop-types rule that will warn you if some of your props are missing in your prop types definition, like this:

estlint-plugin-react example

This is good and you should use it if you like it. But that's not sufficient, it won't warn you about extraneous props when you use your component. It will only warn on missing props validation.

Unknown prop warning (DOM components only)

React has a built-in unknown prop warning activated by default. But this only works on DOM components. So if you try to use <div someProp="yep"> it will warn you:

React Unknown Prop warning example

(only if your prop has a capital letter in it, I just discovered this 🀣)

But it won't warn you of extraneous properties on your own reusable components.

The solution: prop-types-exact

Let's change our previous Input.js component to use airbnb/prop-types-exact:

// Input.js

import PropTypes from "prop-types";
import React from "react";

import exactPropTypes from "prop-types-exact";

export default function Input({
  label,
  type
}) {
  return (<label>{label} <input type={type} /></label>)
}

Input.propTypes = exactPropTypes({
  label: PropTypes.string,
  type: PropTypes.string
});
Enter fullscreen mode Exit fullscreen mode

Now let's refresh our browser and page using <Input type="text" labelText="name" />:

prop-types-exact example

πŸ™Œ NICE! Now I can directly see that I passed down some prop that is not recognized by my component: fast and easy debugging instead of a blank console.

ESLint configuration

If you start wrapping your proptypes with exactPropTypes then eslint-plugin-react will no more recognize where are your prop types declared. To fix this, add propWrapperFunctions (an eslint-plugin-react configuration) to your ESLint settings:

{
  "settings": {
     "propWrapperFunctions": [
        "exactPropTypes"
      ]
   }
}
Enter fullscreen mode Exit fullscreen mode

Summary

Using React, Prop Types, ESLint and eslint-plugin-react you can:

  • know when a proptype is missing
  • know if you're using a prop on a component that is not defined as a proptype
  • know when a proptypes is not used in your component
  • know if you're passing down a wrong proptype (like a number instead of a string)

Bonus: generating Prop Types with VSCode

There's an extension that you can use to generate proptypes easily with VSCode: React PropTypes Generate and it looks like this:

React PropTypes Generate VSCode extension example usage

Going further: Static Type Checking

As the React documentation says, on bigger codebases static type checking can help you detect those cases too. As I am not using static type checking I can't tell you if all the cases we saw in this article are covered. If you're using TypeScript or Flow, let me know in the comments how's the experience on extraneous proptypes usage.

PS: As you guess a friend would not interrupt you in the middle of a coding session BUT that's just for the story 😘

Thanks!

Top comments (4)

Collapse
 
devinrhode2 profile image
Devin Rhode

I need this but for typescript. Even TS 4.1.2 takes in extra unknown props without issues :(

Collapse
 
vvo profile image
Vincent Voyer

Hm actually I jumped into the TypeScript wagon today and had good surprises: it does check for extraneous props as long as you type props of your own components.

Example:

Collapse
 
devinrhode2 profile image
Devin Rhode

Wow it actually does work... codesandbox.io/s/warn-against-extr...
Our tooling in our project needs to get updated... It's using some older CRA but I want to just use Next.js. Of coruse, we'd have to tell Next.js "Our whole App component should not be server-side rendered" via the component wrapper, but it'd be much easier to stay on the bleeding edge that way

Collapse
 
kendalmintcode profile image
Rob Kendal {{β˜•}}

Woah, that VS Code extension! Game changer!!