가수면

useNavigate에 대한 고찰 (?) 본문

일지

useNavigate에 대한 고찰 (?)

니비앙 2023. 2. 23. 18:41

이전 글에서 이어짐

https://jhchoi1182.tistory.com/141

 

클라이언트 전역 상태 관리 Redux Vs React Query

코드 리팩토링 도중 전역 상태 관리는 리액트 쿼리로도 가능한데(데이터를 저장하고 뽑아쓰면 리렌더링까지 일어나는 것을 확인) 그럼 리덕스는 안 써도 되는 것 아닐까 하는 생각에서 실험 시

jhchoi1182.tistory.com

 

지금은 공부를 하며 보는 눈이 트여(?) 위 글의 결론을 수정한 상태지만, 당시만 해도 나는 '리액트 쿼리의 캐싱된 데이터는 state가 아니라 data였다.'라는 생각을 하지 못하고 'setQueryData를 하는 곳에서는 리렌더링이 이루어지는데, 뽑아서 쓰기만 하는 컴포넌트에서는 리렌더링이 일어나지 않는다'라고 생각했었다.

 

컴포넌트 라이프 사이클에 대해 무지했었기 때문에 내린 결론이었지만, 지금 생각해 봐도 충분히 오해할 만한 상황이었다.

실제로 상태값 건드리는 것 없이 setQueryData를 했을 때 리렌더링이 일어났었으니까.

 

어쨌든 그렇게 공부를 하고 깨달음을 얻어 올바른 결론을 도출은 해놨는데... 이상하게 퍼즐이 맞지 않는 것 아닌가.

 

'어... 그럼 setQueryData만 해주는 푸터는 리렌더링이 일어나면 안 되는데?;;;;;'

 

그래서 나는 당시의 커밋으로 되돌아가 상황을 파악하는 시간을 가져보기로 했다.

의문 1. 왜 푸터는 리렌더링이 일어났는가?

코드 진짜 못 짰다..

답은 금방 찾을 수 있었다.

 

버튼을 누를 때마다 main컴포넌트로 navigate가 발생했고, 푸터가 다시 마운트가 되며 리렌더링이 일어난 것이다.

그런데 나는 의문이 더 깊어져만 갔다;

그럼 "/" 경로에 위치한 main 컴포넌트는 왜 리렌더링이 안 되는가...? 

의문 2. Main 컴포넌트는 왜 리렌더링이 발생하지 않았는가?

Main 컴포넌트의 자식 컴포넌트로 묶여있는 Footer

아래를 보면 알 수 있듯, navigate("/") 면 Main 컴포넌트가 마운트 되어야 한다.

 

Main이 마운트 됐으니까 Footer가 리렌더링이 일어날 수 있었을 것이다.

근데 Main은 리렌더링이 안 일어나는데 푸터만 리렌더링이 발생하는 현상을 나는 도저히 이해할 수 없었다.

 

내가 무얼 놓치고 있는 것일까?

 

하염없이 원인을 찾다가 나는 확장 프로그램이 알려주는 힌트를 쫓아가 보기로 했다.

 

극혐;

리렌더링이 일어나는 곳을 보여주고 있다.

보다시피 모든 곳에서 리렌더링이 일어나고 있다...(메모이제이션 작업 전 상황이다!!!)

Main 컴포넌트는 몰라도, 적어도 그 자식 컴포넌트들은 제대로 리렌더링이 일어나고 있다는 건 확실한 것 같다.

 

나는 푸터의 콘솔을 지운 뒤, Main > DiaryList > Diaries > Diary 컴포넌트에 모두 콘솔을 찍어보았다.

 

그러자...

 

Main > DiaryList > Diaries > Diary 이 두 컴포넌트만 리렌더링이 발생하고 있었다!

 

나는 한동안 코드를 뒤적이다가 차이점을 찾을 수 있었다.

처음 생각한 건 props였다.

그러나 props가 바뀌는 조건이라면 코드상으로 DiaryList에서부터 리렌더링이 일어났어야 했다.

그걸 빼고 나니 하나밖에 없었다.

바로 Diaries와 Footer에만 useNavigate가 임포트 되어 있다는 것!

Diaries의 자식 컴포넌트인 Diary는 부모 컴포넌트가 리렌더링 됐으니 리렌더링이 일어나는 게 당연했을 것이다.

 

그러면 또 여기서 발생하는 의문.

의문 3. navigate로 이동하게 되면 navigate를 쓰는 컴포넌트만 리렌더링이 발생하나? 

 

일단 다른 라우터로 넘어갈 때의 상황은 제외다. 마치 새로고침 하듯이 사용했을 때가 조건일 것이다.

 

그럼 Diaries만 놓고 왜 리렌더링이 일어났냐를 생각했을 때, 정말 말도 안 되는 원리인데...

차이점이라곤 navigate밖에 없었다.

 

나는 한 가지 가설을 세웠다.

만약 useNavigate가 임포트 되어있는 것이 조건이라면, Main에 임포트 하는 것만으로도 리렌더링이 일어날 것이다.

 

웃긴다.

임포트 하는 것만으로 리렌더링이 일어난다니. 이게 무슨 말이 되는 소리

 

네?

 

농담 안 하고 딱 밑줄 친 두 줄만 추가했는데 리렌더링이 일어났다...;

 

대체 무슨 원리인지 검색, 깃허브 이슈, 공식 문서를 뒤져봤지만 별 다른 내용을 찾을 수 없었다.

이것에 관해선 나중에 좀 더 지식이 쌓여 라이브러리를 뜯어볼 정도가 되었을 때 직접 알아보는 것도 재밌을 것 같다.

어쨌든 결론

 

정말 이상한데;

navigate를 새로고침하듯이 사용하면 navigate가 임포트 되어있는 컴포넌트만 마운트가 된다;;;

 

'일지' 카테고리의 다른 글

레이아웃 세로 너비  (0) 2023.05.05
라이브러리 오류  (0) 2023.04.21
실전 프로젝트 회고  (0) 2023.02.13
쓰곰그리곰 프로젝트 최적화 작업  (0) 2023.02.11
프로젝트 마무리는 어디로...  (1) 2023.02.05
Comments