DREAMCARD_최종프로젝트_ReactHookForm을 사용한 글꼴 선택 preview반영

정소현·2024년 10월 28일
0

팀프로젝트

목록 보기
28/50

지난번 시간에 이어 사용자가 맨 처음 글꼴을 선택하였을 때 전체 미리보기에 글꼴을 적용시켜 커스텀할 수 있도록 설정해주었다.
이 기능을 구현하기 위해 ReactHookForm과 useState, useEffect를 사용하였다.

☘️ 구현한 방법

  1. 커스텀을 진행하는 create > card > page.tsx에서 method를 선언하여 useForm을 받았다.
  2. Form을 받아와서 watch를 사용하기 위해 부모컴포넌트 (create > card > page.tsx)에서 <FormProvider {...methods}> 로 스코프를 지정해주고 spread연산자를 이용하여 값을 받아왔다.
  3. 유저가 글꼴을 눌러볼 때마다 (method가 변화가 있을 때마다)
    값을 받아와 적용이 되어야했기에 useEffect를 사용하였다.
  4. 그리고 useState()를 이용해 method에 저장되어있는 글꼴을 가져와 저장하였고
  5. style에 적용될 수 있도록 해주었다.

// useForm을 이용하여 form을 받음

const methods = useForm<InvitationFormType>({
    mode: 'onChange',
    defaultValues: {
      bgColor: { r: 255, g: 255, b: 255, a: 1, name: '흰색' },
      mainPhotoInfo: {
        leftName: '',
        rightName: '',
        icon: '',
        introduceContent: '',
        imageUrl: '',
        fontName: '',
      },
      ...

// FormProvider로 값을 받아올 스코프를 지정

<div className='fixed bottom-0 left-0 right-0 px-4 z-10'>
        <FormProvider {...methods}>
          <form
            className='bg-[#bfbfbf] bg-opacity-50 px-4 rounded-lg h-[320px] z-10'
            onSubmit={methods.handleSubmit(onSubmit)}
          >
            <div className='w-full flex items-center justify-end'>
              <button
                type='button'
                onClick={handleDebouncedPrevious}
                className='bg-red-300'
                disabled={currentStep === 1}
              >
                <MdNavigateBefore />
              </button>
              <button
                className='bg-blue-300'
                type='button'
                onClick={handleDebouncedNext}
                disabled={currentStep === refs.length}
              >
                <MdNavigateNext />
              </button>
            </div>

            {currentStep === 1 && <MainPhotoInput />}
            {currentStep === 2 && <PersonalInfoInput />}
            {currentStep === 3 && <AccountInput />}
            {currentStep === 4 && <WeddingInfoInput />}
            {currentStep === 5 && <NavigationDetailInput />}
            {currentStep === 6 && <GuestInfoInput />}
            {currentStep === 7 && <MainViewInput />}
            {currentStep === refs.length && (
              <button
                className='w-full'
                type='submit'
              >
                제출
              </button>
            )}
          </form>
        </FormProvider>

// useState()에 현재 선택된 글꼴 상태를 저장 & useEffect()를 사용해 변화가 생길 때마다 리렌더링

  const subscribeFont = () => {
    const subscriptionFont = methods.watch((value) => {
      const font = value?.mainPhotoInfo?.fontName;
      if (font) {
        setSelectedFont(font);
      }
      return () => subscriptionFont.unsubscribe();
    });
  };

  useEffect(() => {
    subscribeBackgroundColor();
    subscribeFont();
  }, [methods]);

// 적용한 부분

<div
      className={`relative w-full h-full font-${selectedFont}`}
      style={{
        backgroundColor: backgroundColor,
        fontFamily: selectedFont,
      }}
    >

0개의 댓글