Avoid repeating yourself by centralizing PropTypes
There are three popular ways to handle types in React: PropTypes, TypeScript and Flow. This post is about PropTypes, which are currently the most popular.
📊 For enforcing types in React, I typically use…#react
RT's appreciated
— Cory House (@housecor) September 23, 2017
-
- Component accepts an object? Declare the object’s shape.
- Prop only accepts a specific list of values? Use oneOf.
- Array should contain numbers? Use arrayOf.
- You can even declare your own types. AirBnB offers many additional PropTypes.
In real apps with large objects, this quickly leads to a lot of code. That’s a problem, because in React, you’ll often pass the same object to multiple components. Repeating these details in multiple component files breaks the DRY principle (don’t repeat yourself). Repeating yourself creates a maintenance problem.
The solution? Centralize your PropTypes.
Here’s How to Centralize PropTypes
I prefer centralizing PropTypes in /types/index.js.
I’m using named imports on line 2 to shorten the declarations. ?
And here’s how I use the PropType I declared above:
// types/index.js
import { shape, number, string, oneOf } from 'prop-types';
export const userType = shape({
id: number,
firstName: string.isRequired,
lastName: string.isRequired,
company: string,
role: oneOf(['user', 'author']),
address: shape({
id: number.isRequired,
street: string.isRequired,
street2: string,
city: string.isRequired,
state: string.isRequired,
postal: number.isRequired
});
});
I use a named import to get a reference to the exported PropType declaration on line 2. And I put it to use on line 13.
Benefits:
- The centralized PropType radically simplifies the component’s PropType declaration. Line 13 just references the centralized PropType, so it’s easy to read.
- The centralized type only declares the shape, so you can still mark the prop as required as needed.
- No more copy/paste. If the object shape changes later, you have a single place to update. ?
Here’s a working example on CodeSandbox.
Extra Credit: Generate Your PropTypes
Finally, consider writing some custom code to generate your PropType declarations from your server-side code. For example, if your API is written using a strongly typed language like C# or Java, consider generating your PropType declarations as part of your server-side API build process by reading the shape of your server-side classes. This way you don’t have to worry about keeping your client-side PropTypes and your server-side API code in sync. ?
Side-note: If you know of a project that does this for any server-side languages, please reply in the comments and I’ll add a link here.
Edit: You can convert JSON into PropTypes using transform.now.sh. ?
Summary
- Declare your PropTypes as explicitly as possible, so you know when you’ve made a mistake.
- Centralize your PropTypes to avoid repeating yourself.
- If you’re working in a strongly typed language on the server, consider generating your PropTypes by reading your server-side code. This assures your PropTypes match your server-side types.
Looking for More on React? ⚛️
I’ve authored multiple React and JavaScript courses on Pluralsight (free trial).