Mike Schutte
Posted on December 5, 2020
So there I am wanting to make Storybook stories for four states of a component that fetches its own data by way of an Apollo Client hook.
The four states are:
- Loading š
- Error šØ
- No data š
- Data š
I have Mock Service Worker (MSW) set up to intercept network calls. It's pretty straight forward to set up the mocks for the two data states (empty and present) with MSW's context.data
and the error state with context.errors
.
But how do I render a component in its loading state indefinitely for the purpose of viewing it in a Storybook demo?
I didn't find anything existing on the usual suspects of Stack Overflow, GitHub issues, and or here on DEV, so I went back to the MSW docs and found the perfect solution:
I tried using Infinity
as the duration at first, but to no avail. I figure one hour is more than enough to adequately work on or review the loading state UI.
Here is my final implementation:
graphql.query<GetTagsQuery, GetTagsQueryVariables>(
"GetTags",
(_req, res, ctx) => {
// 1 hour delay to view the loading state
return res(
ctx.delay(1000 * 60 * 60 * 60),
ctx.data(newGetTagsData({}))
);
}
)
And here is all of the relevant story code:
import * as React from "react";
import { Flex, Heading } from "@chakra-ui/react";
import { Meta, Story } from "@storybook/react";
import { worker } from "mocks/browser";
import { graphql } from "msw";
import { GetTagsQuery, GetTagsQueryVariables, newGetTagsData } from "api";
import ViewTags from ".";
export default {
title: "Features/View Tags",
component: ViewTags,
decorators: [
(story) => (
<Flex py="20" flex="1" direction="column" justify="center" align="center">
<Heading mb={4} fontSize="6xl">
Avett Rx
</Heading>
{story()}
</Flex>
),
],
} as Meta;
const Template: Story = () => <ViewTags />;
export const Loading: Story = Template.bind({});
Loading.decorators = [
(story) => {
worker.use(
graphql.query<GetTagsQuery, GetTagsQueryVariables>(
"GetTags",
(_req, res, ctx) => {
// 1 hour delay to view the loading state
return res(
ctx.delay(1000 * 60 * 60 * 60),
ctx.data(newGetTagsData({}))
);
}
)
);
return story();
},
];
This use case comes from an article I'm publishing soon that outlines setting up a project with all of my favorite tools for React development in 2020:
- Next.js
- TypeScript
- Vercel
- Prettier
- ESlint
- Lint Staged
- Husky
- TypeScript ESLint
- Chakra UI
- Fauna
- GraphQL Code Generator
- Apollo Client
- Storybook
- Jest
- React Testing Library
- Cypress
- Mock Service Worker
- GitHub Actions
š Keep an eye out for it! š
Posted on December 5, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.