일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- AWS 자격증
- JavaScript
- next15
- 티스토리챌린지
- 자격증시험
- aws cloud practitioner 요약 정리
- AWS Cloud Practitioner
- NextJS
- useState
- SSR
- react
- useEffect
- NEXT
- aws 합격
- window 객체
- window.location.pathname
- window.location.search
- aws clp
- 의존성
- aws 자격증 정리
- 오블완
- CLF-C02
- 개발
- aws
- 시험출제
- aws 정리
- 아자아자
- Today
- Total
집중 맞은 도둑력
[React] window.location.pathname을 useEffect안에서 인식 못하는 이유 본문
React에서 window.location.pathname 또는 search를 인식 못하는 이유
우선 저는 URL serachParam을 바꿀 때엔 React Router의 useSearchParam 훅을 이용하여 searchParam을 업데이트합니다. 즉, 페이지가 새로고침되지 않습니다. 이는 SPA의 특징인데요.
React는 기본적으로 SPA(Single Page Application)을 구축하기 위한 라이브러리입니다.
페이지 전환시 전체 페이지를 새로고침하지 않고 변경된 부분만 업데이트 됩니다.
useState를 사용하면 상태가 변경될 때 이를 감지해서 변경될 컴포넌트만 재렌더링을 진행합니다.
let으로 선언한 변수의 값은 변해도 React가 이를 감지하지 못합니다. React 상태 관리 대상이 아니기 때문입니다.
window.location도 마찬가지입니다.
window 객체는 React 감지 대상이 아닙니다.
useEffect(() => {
console.log(window.location.pathname)
}, [window.location.pathname])
useEffect안에 window.location.pathname을 의존성으로 넣고 페이지 전환을 해도 콘솔창에는 아무것도 뜨지 않습니다.
React는 컴포넌트의 상태(state)와 속성(props)를 기반으로 UI를 업데이트합니다.
window 객체 속성 값이 바뀌어도 React는 자동으로 감지하지 못합니다.
해결방법
그렇다면 어떻게 하면 window 객체 속성 값이 바뀌는 것을 감지시키게 할 수 있을까요?
State와 Props로 감지할 수 있으니 이를 활용해보겠습니다.
방법 1.
페이지 전환시 pathname을 useState로 관리한다.
const [pathname, setPathname] = useState(window.location.pathname);
const navigate = (path: string) => {
window.history.pushState({}, '', path);
setPathname(path);
};
방법 2.
popState 이벤트로 나만의 useLocation훅을 만든다.
window.history.pushState, window.history.back, window.history.go 등 페이지 전환시 popState 이벤트가 발생합니다.
popState를 활용해서 pathname 상태를 관리해줍니다.
// useLocation.tsx
import { useEffect, useState } from 'react';
const useLocation = () => {
const [pathname, setPathname] = useState(window.location.pathname);
useEffect(() => {
const onPopState = () => {
setPathname(window.location.pathname);
};
window.addEventListener('popstate', onPopState);
return () => window.removeEventListener('popstate', onPopState);
}, []);
const navigate = (path: string) => {
window.history.pushState({}, '', path);
setPathname(path);
};
return { pathname, navigate };
};
export default useLocation;
방법 3.
React Router의 useLocation() 또는 Tanstack Query의 useLocation() 도움을 받는다.
대부분 프로젝트에서 라우터 라이브러리를 쓰실건데요. 라이브러리 활용하는게 제일 쉽고 빠른 방법 같습니다.
// Test.tsx
import { useLocation, useNavigate } from '@tanstack/react-router';
const Test = () => {
const navigate = useNavigate();
const pathname = useLocation().pathname;
return (
<>
<header className="p-2 flex gap-2">
<a onClick={() => navigate({ to: '/' })} className="cursor-pointer [&.active]:font-bold">
Home
</a>
<a onClick={() => navigate({ to: '/mypage' })} className="cursor-pointer [&.active]:font-bold">
Mypage
</a>
<a onClick={() => navigate({ to: '/chat' })} className="cursor-pointer [&.active]:font-bold">
Chat
</a>
</header>
<div className="p-2">현재 페이지 경로는 {pathname}입니다.</div>
</>
);
};
export default Test;
이렇게 window 객체 속성의 값이 바뀌면 React가 감지할 수 있도록 하는 법에 대해서 알아보았습니다.
이밖에도 DOM 요소, let에 원시 데이터 타입으로 설정한 값이 바뀌는 경우, 객체나 배열의 내부 속성이나 요소가 바뀌는 경우 등이 있습니다. React가 변경을 감지하도록 하려면 useState나 Props로 이를 알리는 것이 필요합니다!
이상 React Router의 useNavigate로 페이지 이동은 하면서
pathname 변경 감지는 window.location.pathname으로 체크하려고 했던 과거의 나에게 바칩니다.
감사합니다!