인프런 커뮤니티 질문&답변

지호손님의 프로필 이미지

작성한 질문수

[리액트 2부] 고급 주제와 훅

[4.4장 메모이제이션 훅] 4.4.9 활용 MyRouter params(풀이)

useMemo내에서 사용되는 window.location.search 를 deps에서 제외한 이유

작성

·

368

0

안녕하세요. 정환님 드디어 강의도 마무리되어가는데

살짝 이해가 안된 부분이 있습니다.

 

URLSearchPrarms 를 통해 query param를 파싱하는 부분을 캐싱하는 부분에서 window.location.search딱 한번만 바뀌고 거의 바뀌지않을 것이라고 이야기하셨는데 같은 페이지에서 navigate가 흔히 있는 요구사항이 아닌가요?

 

저희가 사용하는 Router의 useNavigate를 통해 화면간에 이동할 때마다 변하는 값으로 알아서 넣어두는게 더 이상적이라고 생각하고 실습을 진행했습니다.

 

저희 예제에서는 cart 페이지에서 cart로 이동할 비지니스 요구사항은 없어서 괜찮지만 예를들어 다른 상품이 담겨있는 장바구니로 이동하는 요구사항이 있다면 /cart?productId=CACDA421 => /cart?productId=CACDA423
deps에 window.location.search를 넣어두는게 안전해보이는데 최적화가 필요한 부분이었을까요?

 

답변 2

1

지호손님의 프로필 이미지
지호손
질문자

아 그러네요. query parameter를 따로 상태로 둬야겠군요.

 

리렌더링을 트리거하지않으면 deps에 넣어두는게 의미없 수 있겠네요. React router dom library에서 어떻게쓰는지 확인해보겠습니다

김정환님의 프로필 이미지
김정환
지식공유자

네 이해하신 게 맞습니다.

1

김정환님의 프로필 이미지
김정환
지식공유자

예제에서 구현한 MyRouter는 경로(path)만 상태로 관리했습니다. Router 컴포넌트가 이 상태를 관리하고 있고 컨택스트를 통해 각 컴포넌트들에게 전달하는 구조인데요. 이들 컴포넌트 중에서 상태 변경 함수를 실행해 경로값을 바꾸면 Router 컴포넌트와 하위의 소비자 컴포넌트들이 다시 렌더링 되면서 페이지가 전환됩니다.

하지만 쿼리문자열은 그렇지 않습니다. 브라우져 주소창에만 변경될 뿐 리액티브하게 구현하지 않았습니다. 만약 상태로 관리했다면 이 값을 바꾸는 함수를 통해 주소를 이동하고 쿼리 파싱하는 기능을 메모이제이션할 수 있었을 겁니다. 하지만 지금 어플리케이션에서 쿼리 문자열을 사용하는 화면이 제한적이고 쿼리문자열을 사용하는 화면간에 이동하는 기능이 없어서 구현하지는 않았습니다.

"useNavigate를 통해 화면간에 이동할 때마다 변하는 값으로 알아서 넣어두는게 더 이상적이라고 생각하고 실습을 진행했다"고 하셨는데요. 아마 Router 상태 path에 값을 "/cart?foo=bar" 형태로 넣으셨을 것 같네요. 그런 조건에일 때 라우터의 상태를 컨택스트로 전달받아 이 값을 메모이제이션 훅의 의존성으로 넣어 구현할 수 있을 것 같습니다.

컴포넌트 상태나 인자가 아닌 글로벌 객체의 변수인 window.location.search 값은 아무리 변경하더라도 컴포넌트를 다시 렌더하지 않는다는 점을 유념해 주시면 좋습니다.