1. Context API를 사용하는 것이 최선일까?

Untitled

Untitled

각각 EmailSectionCertificationSection 컴포넌트이다. 현재 구조는 다음과 같다.

// page.tsx
<main>
  <JoinTopNavigationBar />
  <AuthTitleTextMessage text={`재학생 인증을 위해\\n학교 이메일을 입력해주세요`} />
  <InputForm />
  <NoticeSection />
</main>

그리고. InputForm컴포넌트는 다음과 같다.

// components/InputForm.tsx
<div>
  <EmailSection
    register={register}
    handleSubmit={handleSubmit}
    email={watch('email')}
    isError={!!errors.email}
  />

  <CertificationSection
    register={register}
    handleSubmit={handleSubmit}
    certificateNumber={watch('certificateNumber')}
  />
</div>

여기서, 두 컴포넌트에 넘겨주는 props인 register, handleSubmit, watch, isError는 모두 react-hook-form의 훅인 useForm에서 받은 값이다. 두 컴포넌트에 넘겨주는 props또한 거의 일치한다. 그렇기에 Context로 묶으면 useForm에서 받은 methods만 context로 관리하면 된다. 이 방법이 정말 최선일까?

Context API를 사용하는 것이 가장 걱정되는 부분은 리렌더링 이슈이다. CertificationSection의 값을 다루는데 EmailSection이 리렌더링될 수 있다는 사실이다. 왜냐하면, Context API는 context값이 바뀌면 Context를 사용하고 있는 모든 컴포넌트가 리렌더링이 일어나기 때문이다.

props로 컴포넌트에 넘겨주고 있는 현재, 각 컴포넌트를 React.memo로 메모이제이션을 해두어서, 한 컴포넌트가 리렌더링이 일어날 때 다른 컴포넌트가 리렌더링이 일어나지 않는다.

사실, React.memo를 사용할 때 넘겨주는 props에 함수인 handleSubmit이 있어서 이 함수를 useCallback으로 메모이제이션을 해주어야 렌더링 이슈가 해결될 줄 알았다. handleSubmit을 메모이제이션을 하지 않았는데 어떻게 렌더링 이슈가 해결이 된 것일까?

본론으로 들어가서, 이 구조를 Context API를 사용하여 넘겨주는 props를 줄이는 것이 더 좋은 구조라고 할 수 있을까? props를 넘겨주는 코드와 컴포넌트의 로직이 분리되니 코드가 확실히 깔끔해지긴 할 것이다. 어떤 구조가 더 좋은 구조라고 할 수 있을까.

1. Context API 쓰는 게 맞을까?

Untitled

<CreateMeetingContextProvider>
  <ImageSection />
  <TitleSection />
  <Spacing size={15} />
  <DescriptionSection />
  <DateSection />
  <LocationSection />
  <NumberSection />
  <Spacing size={15} />
  <SubmitSection />
</CreateMeetingContextProvider>

Context Provider로 각 input 컴포넌트를 감쌌다. 과연 이게 좋은 구조일까? Context값이 변경이 되면 모든 Context를 가지고 있는 컴포넌트가 리렌더링이 일어난다. 즉, 제목에 값을 입력하면 다른 모든 컴포넌트도 리렌더링이 일어난다는 것이다. 그래서, 각 컴포넌트에 memo를 이용하여 컴포넌트 리렌더링을 최소화하였다.

그럼에도 불구하고 swiper를 이용한 캘린더와 모임 인원 input의 리렌더링 이슈는 막지 못하였다.

다른 해결책이 필요하다.

이러한 단일 페이지에서 Context를 사용하는 것이 정말 최선일까?