Tip for React PropTypes with Storybook

I’ve recent­ly begun work­ing with React.js, and I’m real­ly enjoy­ing it ! There’s so much to learn, but there’s one tip I’ve picked up that’s sav­ing me some time.

I was doing some research and I came across this bril­liant arti­cle called CSS Archi­tec­ture with Reac­tJS. In it was a clever way of defin­ing our props once, and re-using across prop types and sto­ries in Sto­ry­book.

We’re going to be using Object.values. From MDN :

The Object.values() method returns an array of a giv­en object’s own enu­mer­able prop­er­ty val­ues, in the same order as that pro­vid­ed by a for…in loop (the dif­fer­ence being that a for-in loop enu­mer­ates prop­er­ties in the pro­to­type chain as well).


Let’s say we have a <Button /> com­po­nent that we can apply dif­fer­ent themes to. We can set it up like so in our src/components/button/index.js file :

  export const ButtonTheme = {
    PRIMARY: 'primary',
    SECONDARY: 'secondary'
  }

Then, we can define our prop types :

  Button.propTypes = {
    theme: PropTypes.oneOf(Object.values(ButtonTheme))
  }

Final­ly then, in stories/button.js we can pull this in and ref­er­ence it :

  import React from 'react'
  import { storiesOf } from '@storybook/react'
  import { withKnobs, select} from '@storybook/addon-knobs'
  import Button, { ButtonTheme } from '../src/components/button'

  storiesOf('Button', module)
    .addDecorator(withKnobs)
    .add('Simple button', () => (
      <Button
        theme={select(
          'Theme',
          Object.values(ButtonTheme),
          ButtonTheme.PRIMARY)
        }
      >
        Click me!
      </Button>
  ))

So we only have to define the dif­fer­ent themes once, and it’ll pro­pogate across our prop types and knobs’ in Sto­ry­book auto­mat­i­cal­ly ! Magic.