useEffect가 두 번 실행하는 것에 대하여 🤔

이도경·2023년 2월 26일
0

fRONTeND

목록 보기
5/14
post-thumbnail

문제발생...

ReactJs 개발에 많이 쓰이는 Hooks 중 useEffect 가 있습니다.
하지만 이 Hook를 mounted 상황에 사용하려하면 항상 두 번 실행됩니다..

해결법..? 🧐

간단한 구글링을 통한 해결법 중 하나는 <React.StricMode>를 제거하는 것 입니다.

하지만…

분석!

StricMode란 앱의 잠재적인 문제에 대해 알아내기 위해 엄격하게 검사하는 과정을 의미합니다.

위의 사진의 경우 <APP/> 컴포넌트를 포함하여 모든 자식 컴포넌트를 검사하겠네요.

추가로 다음과 같이 도움됩니다.

  • 안전하지 않은 생명주기를 사용하는 컴포넌트 발견
  • 레거시 문자열 ref 사용에 대한 경고
  • 권장되지 않은 findDOMNode 사용에 대한 경고
  • 예상치 못한 부작용 검사
  • 레거시 context API 검사
  • Ensuring reusable state

여기서 든 생각! 이러한 안전 장치를 제거하는게 과연 옳을까요? 저는 절대 아니라고 생각하기에 조금 더 깊게 알아보겠습니다.

재사용 가능한 상태 보장

공식 문서 내 stric-mode 관련 섹션을 확인했습니다.

React는 빠른 사용자 경험을 위해, unmount 전에 사용된 것과 동일한 컴포넌트 상태를 사용하여 트리 remount를 지원합니다.

이 기능을 사용하면 React의 성능이 즉시 향상되지만, 여러 번의 mount 및 파괴되는 효과에 대해 컴포넌트가 탄력적이어야 합니다. 대부분의 효과는 변경 없이 작동하지만 일부 효과는 삭제 콜백을 제대로 정리하지 못하거나 한 번만 mount 삭제된다고 암시적으로 가정합니다.

이러한 문제 때문에, React는 Strick Mode에 개발 전용 검사를 도입하여 이 새로운 검사는 app의 컴포넌트가 처음 mount 될 때마다 모든 컴포넌트를 자동으로 unmount하고 다시 mount하여 두 번째 mount에서 이전 상태를 복구합니다.

해당 기능을 사용하여 strick mode에서 볼 수 있는 개발 동작을 시연하려면, React가 새로운 컴포넌트를 mount할 때 어떻게 작동하는지 고려하여야합니다. 이 변경 사항이 없으면 컴포넌트가 mount될 때 React는 다음과 같은 실행을 합니다.

* React mounts the component.		//first mount
  * Layout effects are created.
  * Effects are created. 

React18에서 시작된 strick mode를 사용하면 개발 중에 컴포넌트가 mount될 때마다, React가 컴포넌트를 즉시 unmount하고 remount하는 과정을 거칩니다.

* React mounts the component.		//first mount
    * Layout effects are created.
    * Effects are created.
* React simulates effects being destroyed on a mounted component.		//unmount
    * Layout effects are destroyed.
    * Effects are destroyed.
* React simulates effects being re-created on a mounted component.		//remount
    * Layout effects are created
    * Effect setup code runs

두 번째 mount에서 React는 첫 번째 mount 상태로 복구합니다.

이는 개발 모드에만 적용되며 프로덕션 동작은 변경되지 않습니다 .

결론...

개발 모드에서만 실행되는 문제임으로 빌드된 상태에서는 확인할 수 없었습니다.


개발 모드 : 두 번을 실행합니다.


배포 환경 : 한 번만 실행합니다.

참고 문서

https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state

profile
안녕하세용

0개의 댓글