본문 바로가기
개발개발/WorkRoot_워크루트

스토리북 (storybook) 트러블 슈팅 - 2 (React-hook-form)

by yelimu 2025. 1. 3.

컴포넌트 내부에 리액트 훅폼 로직이 녹아있어서 스토리북에서 리액트훅폼의 form provider가 필요했다.

-> formProvider로 Story를 감싸줘야한다


시간을 선택하는 컴포넌트를 작성하면서 

useFormContext 를 사용해 폼 데이터를 컴포넌트 내부에서 관리하도록 작성하는 바람에 

스토리북에 에러가 났(었나보)다

// timePickerInput.tsx
"use client";
import BaseInput from "../text/BaseInput";
import { useDropdownOpen } from "@/hooks/useDropdownOpen";
import TimeOption from "./pickerComponents/TimeOption";
import { useFormContext } from "react-hook-form";

const TimePickerInput = () => {
  const { register, setValue, watch } = useFormContext(); // 여기 💥
  const timeValue = watch("timepicker");
  const handleTimeSelect = (time: string) => {
    setValue("timepicker", time);
    handleOpenDropdown();
  };
  const { isOpen, handleOpenDropdown } = useDropdownOpen();
  
  return (
    <div onClick={handleOpenDropdown} className="relative">
      <div>{isOpen}</div>
      <BaseInput
        type="text"
		// prop 중략..
        {...register("timepicker")}
      />
      {isOpen && <TimeOption className="absolute top-[58px] lg:top-[68px]" handleTimeSelect={handleTimeSelect} />}
    </div>
  );
};
export default TimePickerInput;

나중에는 컴포넌트 내부에는 리액트 훅폼 관련 코드를 상위 컴포넌트로 빼주어서 최종 코드는 이와 다르다. 

=> 이 경우 스토리에서도 Provider가 불필요하다. 

// TimePicker.stories.tsx
import { FormProvider, useForm } from "react-hook-form";

const meta = ()=>{
  title: "Design System/Components/Date-Time-Day Picker/TimePicker",
  component: TimePickerInput,
  parameters: {
    layout: "centered",
  },
  // FormProvider를 제공하는 데코레이터 추가
  decorators: [
    (Story) => {
      const methods = useForm();
      return (
        <FormProvider {...methods}>
          <Story />
        </FormProvider>
      );
    },
  ],
} satisfies Meta<typeof TimePickerInput>;

 

decorators 로 렌더링 환경을 정의해주면서 react-hook-form에서 제공하는 FormProvider 로 감싸주었다.


이와 비슷하게 

전역 상태나 컨텍스트를 제공하는 라이브러리를 스토리북에서 사용할때 Provider로 감싸주어야 하는 라이브러리로는

Redux, React Router, Theme Provider, Context API 등이 있다.