Storybook with React, Redux, and Material UI

Jason Sturges
JavaScript in Plain English
4 min readJan 28, 2021

--

Photo by Alex Block on Unsplash

Navigating the complexities of Storybook with React CRA, Redux, Material UI theming, proxies, and routing can be tricky.

Storybook is invaluable for developing and testing UI components in isolation, enabling rapid prototyping while forcing critical thinking to the API of your components and containers.

Initial Setup

Setting up Storybook with React is simple using the npx sb init command. For example, to scaffold a Create React App with Storybook, simply execute the following:

npx create-react-app my-app
cd my-app
npx sb init

There’s been some issues recently with Storybook and CRA — you may have encountered babel errors after executing npx sb init such as:

Error: Cannot find module ‘babel-loader’

Or, after adding babel loader:

ERROR in ./.storybook/storybook-init-framework-entry.js
Module not found: Error: You attempted to import …/my-app/node_modules/@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils.js which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.
You can either move it inside src/, or add a symlink to it from project’s node_modules/.

Thankfully these have resolved by the Storybook team.

To try latest features, install as:

npx sb@next init

Once complete, Storybook will scaffold configuration and an example set of stories under:

  • .storybook/ — Configuration of Storybook
  • src/stories/ — Example stories

To start Storybook, execute:

yarn storybook

Then, navigate to http://localhost:6006/ to view the interface:

Creating Storybook Docs

Storybook uses MDX for creating Storybook Docs — a great way to document your components.

Under the src/stories folder, create any quantity of MDX documentation by creating a new file named [topic].stories.mdx and specifying the title in the <Meta tile="section/topic]" /> meta block.

Here’s an example introduction.stories.mdx file:

Above example combines markdown with styled HTML, would would produce the following page in the Storybook UI:

Creating a Story

Storybook automatically scaffolds some example stories, in which example components are defined in the src/stories folder. Of course, you would access your components as normal from src/ — these are only for demonstration purposes. In fact, you can delete everything in that stories folder to start fresh.

Under the src/stories folder, create any quantity of stories by adding new files named [topic].stories.js to group a collection of components.

In each story, load React and components for the story, exporting a title, argument types, and components to load in Storybook:

Above examples would show a Button component that has the following argument types:

  • Background Color, using the a color control
  • Primary, using a boolean toggle switch
  • Label, using a string text input
  • Size, using a radio control to display an enumeration of possible options

By default, the component will default to primary enabled with label “Primary Button” by passing args to the component.

Storybook will load this story as follows:

There’s a wide range of controls builtin, defined in Storybook’s Essential Controls documentation. These include array, boolean, number, range, text, color, date, radio, check, and select.

Proxying Endpoints and Web Sockets

If your development environment incorporates multiple servers providing streaming data, static assets, and APIs through other backend servers, you may need to implement middleware to proxy the requests.

For example, if your React app implements proxies leveraging http-proxy-middleware, you can incorporate the same functionality with Storybook by creating a file under the .storybook/ folder named: middleware.js that includes:

Above, web socket requests are proxied to localhost port 4002, and two endpoints of /photosand /apiare proxied to localhost port 3001.

Redux, Theming, and Routing

Three additional topics are grouped here, as they all relate the to the preview decorator of Storybook.

  • Incorporating a Redux store
  • Integrating with Material UI theme provider
  • Handling routing issues with React Router

All stories can implement a global decorator to provide this functionality by creating a file under the .storybook/ folder named: preview.js that includes the following:

This will wrap functionality around stories rendered by Storybook.

Redux

Storybook is more intended for components and properties opposed to containers that manage state in a store.

However, it may be necessary to incorporate a provider in your stories, especially for larger projects with significant lifespan.

In doing so, this might help expose and encourage decoupling logic and presentation; or, just prevent errors if your components tightly integrate with Redux stores.

In the preview decorator, add your Redux provider and store.

Material UI Theming

If your solution incorporates theming, such as Material UI’s theming system, it is ideal to view your components with your theme provider.

In the preview decorator, add your theme provider and theme definition.

React Router

Routing will generally have little meaning in Storybook; however, if your components include functionality such as useLocation hook from React Router DOM, they will throw an error unless some kind of router is implemented.

import { useLocation } from "react-router-dom";const MyComponent = () => {
const location = useLocation();

useEffect(() => {
// something happens...
}, [location]);

To compensate for this, include a router such as MemoryRouter from React Router in the preview decorator.

--

--

Avant-garde experimental artist — creative professional leveraging technology for immersive experiences