[Storybook] Story with useState

문지은·2024년 5월 7일
post-thumbnail

아래와 같이 컴포넌트에서 상태값 변경을 할 경우, 스토리북에서도 상호작용에 따른 상태 변경을 확인할 수 있으면 좋다.

이를 위한 스토리북 스토리 작성법에 대해 알아보자.

  • React를 이용해서 상태관리를 하는 가장 보편적인 방법은 useState를 활용하는 것이다.
  • 일반적으로 스토리 작성시, 컴포넌트에게 전달할 인수를 args 로만 지정하면 스토리북에 컴포넌트가 렌더링 된다.
    • 스토리에 useState로 정의한 상태값과 함수를 전달하기 위해서는 render 함수를 정의하고 그 안에서 state 작성 및 컴포넌트에 전달하면 된다.
  • 주의해야 할 점 1: 스토리 파일에서 reactuseState를 사용할 경우 lint 오류는 없으나 스토리북에서 state 변경 시 아래와 같은 오류가 발생하므로 반드시 스토리북의 useState를 사용해야 한다.
import { useState } from 'react'; // X
import { useState } from "@storybook/preview-api"; // O
  • 주의해야 할 점 2 : render 함수 안에서 useState 를 사용할 때 화살표 함수를 사용하면 아래와 같은 오류가 발생하므로 반드시 함수 표현식을 사용해야한다.
// X
render: (args) => {
  const [selected, setSelected] = useState<string[]>([]);
  return <MultiSelect {...args} selected={selected} onChange={setSelected} />;
},

// O
render: function Render(args) {
  const [selected, setSelected] = useState<string[]>([]);
  return <MultiSelect {...args} selected={selected} onChange={setSelected} />;
},

최종 작성 스토리 코드

import type { Meta, StoryObj } from "@storybook/react";
import MultiSelect from ".";
import { useState } from "@storybook/preview-api";

const meta: Meta<typeof MultiSelect> = {
  component: MultiSelect,
  tags: ["autodocs"],
  title: "Components/MultiSelect",
  argTypes: {
    ...
  },
};
export default meta;
type Story = StoryObj<typeof MultiSelect>;

export const Default: Story = {
  args: {
    label: "지역 선택",
    placeholder: "지역을 선택해주세요",
    required: true,
    options: [
      { label: "서울특별시", value: "Seoul" },
      { label: "부산광역시", value: "Busan" },
      { label: "인천광역시", value: "Incheon" },
      { label: "대구광역시", value: "Daegu" },
      { label: "대전광역시", value: "Daejeon" },
      { label: "광주광역시", value: "Gwangju" },
      { label: "울산광역시", value: "Ulsan" },
      { label: "세종특별자치시", value: "Sejong" },
      { label: "경기도", value: "Gyeonggi" },
      { label: "경상남도", value: "Gyeongsangnam" },
      { label: "경상북도", value: "Gyeongsangbuk" },
      { label: "충청남도", value: "Chungcheongnam" },
      { label: "충청북도", value: "Chungcheongbuk" },
      { label: "전라남도", value: "Jeollanam" },
      { label: "전라북도", value: "Jeollabuk" },
      { label: "강원도", value: "Gangwon" },
      { label: "제주도", value: "Jeju" },
    ],
  },
  render: function Render(args) {
    const [selected, setSelected] = useState<string[]>([]);
    return <MultiSelect {...args} selected={selected} onChange={setSelected} />;
  },
};
profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

0개의 댓글