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
- eslint-plugin-react
- Unknown prop warning (DOM components only)
- The solution: prop-types-exact
- Summary
- Bonus: generating Prop Types with VSCode
- Going further: Static Type Checking
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
};
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:
And:
"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:
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:
(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
});
Now let's refresh our browser and page using <Input type="text" labelText="name" />
:
π 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"
]
}
}
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:
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)
I need this but for typescript. Even TS 4.1.2 takes in extra unknown props without issues :(
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:
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
Woah, that VS Code extension! Game changer!!