본문 바로가기

📂 에러로그

useFunnel과 zustand 동시 사용 시, state 초기화 문제

Opener 프로젝트를 진행하며 Funnel 방식을 처음 경험해 보았습니다. Funnel 방식 도입과 관련하여 꽤나 깊게 고민했던 문제였기 때문에 에러로그로 남겨보겠습니다 😝✏️


Error

  • modal 로직: zustand 이용해서 구현
  • useFunnel 사용 전
    • modal open → zustand 변경 → post 재렌더링 → MainInfo 재렌더링 → state 변화X & input 태그 value 유지
  • useFunnel 사용 후
    • modal open → zustand 변경 → post 재렌더링 → useFunnel 재실행 → Funnel 재렌더링 → Step 재렌더링 → MainInfo 재렌더링 → state 초기화 !!
    • state가 초기화되면서, 모든 input 태그의 value값이 날아가는 문제 발생

=> ❓ 근데 왜 Funnel, Step이 재렌더링되면 state가 초기화될까?

state가 초기화되는 이유

  • 리액트는 같은 위치에 같은 컴포넌트가 있는지 비교 후, state를 유지할지 말지 결정
  • ⇒ 해당 포지션에 다른 컴포넌트가 있는 경우 초기화
  1. post가 재렌더링될 때, useFunnel이 재실행됨
  2. useFunnel 내부에서 선언된 Step과 Funnel 역시 재생성 → 이때, 주소값이 다른 함수객체가 된다 ⇒ 주소값이 달라졌으므로 리액트는 아예 다른 컴포넌트라고 인식! ⇒ 따라서 Funnel 내부 state를 전부 초기화시킨다…………ㅠㅠ

Try1: 원인 파악

  • modal을 local state를 이용해서 열어 MainInfo만 재렌더링이 발생하게 하면 해결된다.
  • ⇒ zustand로 인한 문제라는 것을 인식 (modal과 똑같은 로직을 사용하는 BottomSheet로 테스트해보았으나 결과는 똑같음,, → modal 자체 내부 로직의 문제가 아니라 zustand 사용이 원인이라고 확신!)

Try2: state 초기화를 막을 수 없을까?

  • Step에 key prop 부여 ⇒ 실패 ㅠㅠ
    • 기존에 렌더링되었던 Step이 바뀌지 않았다는 것을 인식하면 state가 초기화 안되지 않을까? 라고 생각함
  • Funnel과 Step에 React.memo 사용 ⇒ 실패 ㅠㅠ
    • React.memo 자체가 children이 재렌더링되어버리면 부모 컴포넌트도 재렌더링되기 때문에 실패,,

Solution

  • useFunnel을 사용하기로 한 이상, zustand를 사용하게 되면 Funnel의 재렌더링을 막을 수 있는 방법은 없다
  • 어차피 현재 디자인 상, 이중 모달을 사용하는 곳이 없으므로 local state로 모달을 관리하기 충분하다고 생각되어
  • modal 로직을 local state를 사용하는 커스텀훅 방식으로 변경하기로 결정하였습니다!