React Pattern: Centralized PropTypes

Avoid repeating yourself by centralizing PropTypes

Grand Central Station, New York, NY

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.

    • 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:

  1. The centralized PropType radically simplifies the component’s PropType declaration. Line 13 just references the centralized PropType, so it’s easy to read.
  2. The centralized type only declares the shape, so you can still mark the prop as required as needed.
  3. 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

  1. Declare your PropTypes as explicitly as possible, so you know when you’ve made a mistake.
  2. Centralize your PropTypes to avoid repeating yourself.
  3. 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).