Moong

[React+Typescript] Storybook에 라우터(react-router-dom) 설정하기 본문

React

[React+Typescript] Storybook에 라우터(react-router-dom) 설정하기

방울토망토 2023. 5. 4. 17:24

storybook에서 react-router-dom 을 포함한 컴포넌트를 불러오면 관련 설정들을 해주어야 합니다!

 

1. storybook-addon-react-router-v6 다운로드

관련 라이브러리를 다운받아줍니다.

🔗 storybook-addon-react-router-v6 Github 링크

# yarn
yarn add -D storybook-addon-react-router-v6

# npm
npm install storybook-addon-react-router-v6

 

2. addon에 router 추가하기 ( => main.ts)

addon array에 storybook-addon-react-router-v6을 추가해줍니다.

// .storybook/main.ts

import type { StorybookConfig } from "@storybook/react-webpack5";
const config: StorybookConfig = {
  stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/preset-create-react-app",
    "@storybook/addon-interactions",
    /* 이부분 추가해줍니다! */
    "storybook-addon-react-router-v6"
  ],
  framework: {
    name: "@storybook/react-webpack5",
    options: {},
  },
  docs: {
    autodocs: "tag",
  },
  staticDirs: ["../public"],
};
export default config;

 

3. decorator에 withRouter 추가하기

 

1️⃣ 전역에서 router를 사용하는 경우

preview.tsx 에 withRouter 추가

모든 story에서 router를 사용하는 경우

.storybook/preview.tsx 에서 decorators 리스트에 withRouter를 추가해줍니다.

// .storybook/preview.tsx
import React from "react";
import type { Preview } from "@storybook/react";
import { withRouter } from 'storybook-addon-react-router-v6';

const preview: Preview = {
  parameters: {
    actions: { argTypesRegex: "^on[A-Z].*" },
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/,
      },
    },
    reactRouter: {
      routePath: '/',
      browserPath: '/'
    }
  },
  /* 이부분 추가! */
  decorators: [withRouter],
};

export default preview;

 

2️⃣ 특정 story에서만 router를 사용하는 경우

해당 스토리 파일에 withRouter 추가

해당 스토리 meta 객체에 withRouter를 추가해줍니다.

⚠️ 이 경우, preview.tsx에서도 withRouter를 추가해주는 경우 에러가 납니다! (꼭 한 곳에서만 추가해주기!)

// Component.stories.tsx
import { withRouter } from 'storybook-addon-react-router-v6';
...
const meta : Meta<typeof Component> = {
  title: 'Example/Component',
  component: Component,
  tags: ['autodocs'],
  /* 이부분 추가! */
  decorators: [withRouter]
};
...

 

4. 주소(Route Path) 설정하기

1️⃣ 전역 주소 설정

preview.tsx 에 reactRouter 추가

모든 story가 rendering 될 때 초기 주소를 통일하고 싶을 때는,

.storybook/preview.tsx 에서 parameters 객체에 reactRouter를 추가해줍니다.

// .storybook/preview.tsx
import React from "react";
import type { Preview } from "@storybook/react";
import { withRouter } from 'storybook-addon-react-router-v6';

const preview: Preview = {
  parameters: {
    actions: { argTypesRegex: "^on[A-Z].*" },
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/,
      },
    },
    /* 이부분 추가! */
    reactRouter: {
      routePath: '/',
    }
  },
  decorators: [withRouter],
};

export default preview;

 

2️⃣ 특정 story 주소 설정

a. meta에 parameters.routePath 추가 : 특정 story 파일의 모든 스토리 주소를 설정하고 싶은 경우
b. story에 parameters.routePath 추가 : 특정 story 파일의 주소를 설정하고 싶은 경우

 

a. 스토리 파일에 있는 모든 스토리 주소 통일

Button.stories.tsx에 있는 모든 버튼 스토리들의 주소"/buttons" 로 설정하고 싶은 경우,

meta 의 parameters에 reactRouter 객체를 추가합니다.

// Button.stories.tsx
...
const meta : Meta<typeof Button> = {
  title: 'Example/Button',
  component: Button,
  parameters: {
    reactRouter: {
      routePath: '/buttons',
    }
  }
};
...

 

b. 스토리마다 주소 다르도록

Buttons.stories.tsx 중 Primary 버튼 스토리의 주소"/buttons/primary" 로 설정하고 싶은 경우,

해당 story 의 parameters에 reactRouter 객체를 추가합니다.

// Button.stories.tsx
...
type Story = StoryObj<typeof meta>;

export const Primary: Story = {
  args: {
    primary: true,
    label: 'Button',
  },
  story: {
    parameters: {
      reactRouter: {
        routePath: '/buttons/:buttonType',
        routeParams: { buttonType: 'primary' }, 
      }
    }
  }
};
...

 

⭐️ reactRouter 객체

앞서 설명했던 reactRouter의 파라미터에 대해 추가 설명입니다.

 

▪️ routePath : url, route 주소

▪️ routeParams : route parameter => useParams 에 대응

▪️ routeState : route 상태 => useLocation 의 state 에 대응

▪️ searchParams : route query => searchParams 에 대응

 

// reactRouter example
reactRouter: {
	routePath: '/users/:userId',
	routeParams: { userId: '42' },
	searchParams: { tab: 'activityLog' },
	routeState: { fromPage: 'homePage' },
}

 

 

결과 화면

storybook 하단에 React Router 탭이 생기면서,

useNavigate 이벤트가 감지된 것을 확인하실 수 있습니다!

 

 

 

그럼 오늘도 제 글이 도움이 되길 바라며,

이만 글을 마치겠습니다! 🍅

Comments