React

Funnel에서의 상태관리 고민

popeyes 2024. 1. 30. 17:03

 

 

 

현재 구조는 최상위 컴포넌트인 OnboardingPage에서 모든 상태를 useState를 통해 관리하고 있다.

 

const OnBoardingPage = () => {
  const { Funnel, setStep } = useFunnel(ONBOARDING_FORM_STEP, ONBOARDING_FORM_STEP[0]);
  const [gifteeName, setGifteeName] = useState<string>('');
  const [imageUrl, setImageUrl] = useState<string>('');
  const [deliveryDate, setDeliveryDate] = useState<string>('');
  const [tournamentStartDate, setTournamentStartDate] = useState<string>('');
  const [tournamentDuration, setTournamentDuration] = useState<string>('');
  const [fileName, setFileName] = useState<string>('');
  const [invitationCode, setInvitationCode] = useState<string>('');
  const [presignedUrl, setPresignedUrl] = useState<string>('');
  const [imageFile, setImageFile] = useState<File | null>(null);
  const [roomId, setRoomId] = useState<number>(0);

 

그리고 각 퍼널 단계마다 필요한 상태를 props로 내려주고 있다.

 


      <Funnel.Step name='NAME'>
          <OnBoardingHeader step={1} onClick={handleFirstHistoryClick} />
          {/* step01 */}
          <NameInput
            onNext={() => setStep(() => 'THUMBNAIL')}
            setGifteeName={setGifteeName}
            gifteeName={onboardingInfo.gifteeName}
          />
        </OnBoardingPageWrapper>
      </Funnel.Step>
      
      <Funnel.Step name='THUMBNAIL'>
        <OnBoardingPageWrapper>
          <OnBoardingHeader step={2} />
          {/* step02 */}
          <ThumbnailInput
            onNext={() => setStep(() => 'PRESENT')}
            setFileName={setFileName}
            setImageFile={setImageFile}
          />
        </OnBoardingPageWrapper>
      </Funnel.Step>
      .
      .
      .

 

이렇게 step05까지 설계되어있다.

 

프로젝트를 진행하면서도 계속해서 이런 구조에 대한 의문이 생겼었다. 

 

최상위 컴포넌트에서 상태를 관리하는 이 구조가 정말 최선인가?

 

물론 장점도 있는 것 같다.

 

어떤 상태가 어디에 전달되는지 명시적이기 때문에 보다 쉽게 이해할 수 있다는 것이다. 

 

그러나, 여러 걱정이 앞서는 것도 또한 사실이다.

 

혹여나 퍼널의 단계마다 데이터 전달이 잘 안되지 않을까? 

 

컴포넌트간의 상태를 공유하기 어렵지는 않을까?

 

상태의 일관성을 유지하기 어렵지는 않을까?

 

향후 온보딩에 더 많은 정보가 필요하다면, 유지보수에 어려움이 있지는 않을까?

 

또한,

 

이러한 구조는 커스텀 훅으로 분리하기엔 어렵지 않은가?

 

그렇다는 말은 곧, 각 퍼널 단계마다의 코드가 길어지고, 관심사에 따라 분리하기 어렵다는 판단이 들었다.

 

그렇다면 어떤 구조가 최선일까??

 

현재 코드의 특징은 다음과 같이 정리할 수 있을 것이다.

 

1. 단계별로 데이터를 수집한다

-> 퍼널의 각 단계에서 데이터를 수집하고 최종적으로 전체 데이터를 서버에 전달하는 형태

 

2. 데이터의 일부만 필요한 경우가 있다.

 

현재로썬, 필요한 데이터가 단순하기에 useState로 관리하는 것도 좋아보이긴 한다.

 

그러나, 추후 단계가 더 추가되거나, 필요한 상태가 더 복잡해진다면, 지금처럼 useState로 계속해서 관리하기엔 힘들 것 같다는 생각이다.

 

context API를 도입해보면 어떨까?

 

아무래도 시도해보지 않은 구현 방식이기에 러닝 커브가 있을 것이고, 코드의 복잡도가 조금은 올라갈 수 있다. 

 

그렇지만 상태 변경이 필요한 경우 중앙에서 한번에 수정할 수 있기에 코드의 일관성을 좀 더 유지할 수 있다는 장점이 있을 것 같다.

 

결국 나의 고민을 정리하자면, 아래와 같다.

 

추후 유지보수 측면에서 미리 리팩토링을 진행하는 것

vs

아직 단순한 데이터만 필요하니 최상위 컴포넌트에서 props로 전달해주는 현재 구조

 

추후에는 context API를 이용하여 리팩토링하는 과정을 블로그에 포스팅 해보겠다.