Increase your productivity with Storybook's new Component Story Format
Tags: webdev, react, productivity, storybookjs
Published: 2019-10-24 21:08:56

---
title: Increase your productivity with Storybook's new Component Story Format
published: true
description: Storybook's recent updates include a new way to define stories. In this post we'll look at how we can take advantage of these new features to increase our productivity
tags: webdev, react, productivity, storybookjs
cover_image: https://thepracticaldev.s3.amazonaws.com/i/i3zfgow0cxm9kdimyibm.png
---

Storybook is an incredible tool for building component based frontend applications. [It helps you develop the parts of your application in isolation and apply some powerful plugins to ensure quality and consistency](https://dev.to/ryanlanciaux/the-magic-of-a-mise-en-place-mindset-for-frontend-development-3ge0). With a recent release of Storybook, there is a new way that we can define our stories that can help us eliminate duplication in other areas of our codebase.

## Component Story Format

Traditionally, Storybook stories look like the following code block:

```javascript
import  React from 'react';
import { storiesOf } from '@storybook/react';

import Card from './Card';

storiesOf('Card', module).add('default', () => {
  return <Card>Something</Card>
});
``` 

These work well and **this traditional format is not going away**, however, there are some extra benefits we get by using the new component story format. 

The new component story format looks like this:

```javascript
export default { title: "activityFeed/ActivityFeedItem" };

export const standard = () => (
  <ActivityFeedItem
    name="Bill Murray"
    conferenceName="Some Conference"
    imageUrl="https://www.fillmurray.com/128/128"
  />
)
```

You may notice that the only Storybook specific item is the default export. The default export is a JavaScript object that takes a title that can be either the title of the story or the path to the story (this example is using a path) and [some additional options](https://storybook.js.org/docs/formats/component-story-format/). 

The story definition is now a standard arrow function.

## Benefits

One of the most immediate benefits that I've found when using the Component Story Format is testing. My tests can now reuse the stories.

I've traditionally had code in my tests that was very similar to the code in my stories for wiring up components (notice that the use of the ActivityFeedItem in this test is very similar to the story above):

```javascript
import React from 'react';
import { render, getByText } from '@testing-library/react';
import ActivityFeed from './ActivityFeed';

it('has Bill Murray', () => {
  const { container } = render(
    <ActivityFeedItem
      name='Bill Murray'
      conferenceName='Some Conference'
      imageUrl='https://www.fillmurray.com/128/128'
    />
  );

  expect(getByText(container, 'Bill Murray is speaking at')).toBeDefined();
})
```

Using the new format, we can leverage the stories we have already created by importing them into our tests:

```javascript
import React from 'react';
import { render, getByText } from '@testing-library/react';

// import our component from storybook 
// instead of re-wiring a new component for the test
import { standard } from './ActivityFeed.stories';

it('has Bill Murray', () => {
  const { container } = render(standard());

  expect(getByText(container, 'Bill Murray is speaking at')).toBeDefined();
})
```

This is especially helpful when you have a component that has multiple states. You can make a story that represents each of the various states and import these stories directly in your tests.


(Very contrived code - not real world scenario BUT should help show the concept):

```javascript
// ActivityFeed.stories.js

export default { title: 'activityFeed/ActivityFeedItem' };

export const withBillMurray = () => (
  <ActivityFeedItem
    name='Bill Murray'
    conferenceName='Some Conference'
    imageUrl='https://www.fillmurray.com/128/128'
  />
)

export const withNicolasCage = () => (
  <ActivityFeedItem
    name='Nicolas Cage'
    conferenceName='Some Conference'
    imageUrl='https://www.placecage.com/128/128'
  />
)

// ActivityFeed.test.js
import { render, getByText } from '@testing-library/react';
import {  withBillMurray, withNicolasCage } from './ActivityFeed.stories';

it('has Bill Murray', () => {
  const { container } = render(withBillMurray());

  expect(getByText(container, 'Bill Murray is speaking at')).toBeDefined();
})

it('has Nicolas Cage', () => {
  const { container } = render(withNicolasCage());

  expect(getByText(container, 'Nicolas Cage is speaking at')).toBeDefined();
})
```

This technique also works with tools such as [Cypress](https://www.cypress.io/)


I'd love to know your thoughts or of any other way that you're achieving better productivity in front-end development with similar strategies.