useNavigate를 사용해서 경로 이동을 해야할 때 발생하는 페이지 공백 오류 해결
페이지 전환 시 보이는 로딩 페이지 구현
구현하려는 기능
useNavigate를 사용해서 경로 이동을 해야할 때 페이지 공백이 발생한다.
결제페이지에서 인보이스 페이지로 넘어가는 과정에서 페이지 공백이 잠깐 발생했다.
이때 notFound 화면이 나오게 되는데 사용자는 결제가 완료되지 않았다고 오해할 수 있는 상황이었다.
그래서 결제페이지에서 인보이스 페이지로 이동하는 사이에 보여질 로딩페이지를 구현하고자 했다.
내가 생각한 로직
1. 로딩 페이지를 만들어서 path경로를 /invoice 로 지정한다.
2. orderId를 전달받아서 새로운 페이지를 불러오기 전에는 /invoice가 기본 경로로 설정되어 loading 페이지가 보여지게 된다.
3. 결제페이지에서 받은 orderId가 /invoice/:orderNumber의 형태로 들어가서 실행된다.
처음 작성했던 코드 (오류 발생)
function Router() {
return (
<BrowserRouter>
<ScrollToTop />
<Nav />
<Routes>
...
<Route path="/invoice" element={<LoadingPage />} />
<Route path="/invoice/:orderNumber" element={<Invoice />} />
...
</Routes>
<Footer />
</BrowserRouter>
);
}
오류가 발생한 부분
<Route path="/invoice" element={<LoadingPage />} />
결제페이지에서 인보이스 페이지로 넘어갈 때 orderId가 들어오지 않고 /invoice로 잠깐 머물게 될 때가 있다.
이때 로딩페이지가 실행되도록 하려는 의도였으나 orderId가 들어와도 넘어가지 않는 오류가 발생하였다.
오류가 발생한 원인
path 경로를 /invoice 그대로 쓸 경우 /invoice/:orderNumber 보다 우선적으로 적용된다.
따라서 orderId가 들어와도 계속 /invoice에서 경로가 변경되지 않았다.
해결 방안
구글링을 통해 찾은 방법 중 하나가 outlet을 사용하는 중첩라우팅이었다.
중첩라우팅을 통해 컴포넌트를 바꿔줄 수 있다고해서 시도해보았다.
<Route path="/invoice/:orderNumber" element={<Invoice />}>
<Route path="LoadingPage" element={<LoadingPage />}></Route>
</Route>
/* LoadingPage.js */
import { Outlet } from 'react-router-dom';
function About() {
return (
<div className="loadingPage">
<img src="/images/loadingPage/loadingPage.png"></img>
</div>
);
}
export default LoadingPage;
BUT! 원하는 결과가 나오지 않았다.
오류가 발생한 부분
예상했던 것과 달리 로딩페이지가 나오지 않고 또 notFound 페이지만 나오다가 인보이스 페이지로 넘어갔다.
중첩 라우팅으로 작성한 로딩페이지가 실행되지 않았다.
오류가 발생한 원인
애초에 중첩라우팅의 개념을 잘못 이해하고 있었다.
중첩라우팅은 한 페이지내에서 컴포넌트를 특정조건에 따라 다르게 보여줄 때 사용하는 것으로
나처럼 페이지를 이동할 때 페이지 사이에 나오는 페이지를 넣는 것과는 달랐다.
해결 방안
중첩라우팅처럼 컴포넌트를 끼워넣는 방식은 애초에 잘못된 접근방식이라는 것을 깨닫고 다른 방법을 찾아보왔다.
그러던 중 팀원이 구글링을 통해 /뒤에 *를 붙이면 /뒤에 어떤 문자가 오든
무조건 해당 컴포넌트가 보이도록 할 수 있다는 것을 찾아냈다.
그래서 바로 /invoice뒤에 /*를 붙여서 실행해보았다.
<Route path="/invoice/*" element={<LoadingPage />} />
<Route path="/invoice/:orderNumber" element={<Invoice />} />
이때 또 하나 유의해야 할 점은 <Route path="/invoice/*" element={<LoadingPage />} />를
반드시 먼저 라우팅되도록 해야한다는 것이다.
왜냐하면 <Route path="/invoice/*" element={<LoadingPage />} />를 먼저 실행하고
<Route path="/invoice/:orderNumber" element={<Invoice />} />를 실행하도록 해야
/invoice에 해당하는 모든 경로는 로딩페이지를 보여주되,
만약 <Route path="/invoice/:orderNumber" element={<Invoice />} />일 경우에는
인보이스 페이지를 보여주도록 하기 때문이다.
이렇게 하면 orderId를 전달받아서 새로운 페이지를 불러오기 전에는
/invoice/*가 기본 경로로 설정되어 loading 페이지가 보여지게 된다.
최종 수정된 코드
'Web Development > React' 카테고리의 다른 글
날짜 및 시간 예약 기능 구현하기 / with react-datepicker (0) | 2023.07.06 |
---|---|
React / 컴포넌트 재사용 / Button component (0) | 2023.05.18 |
React / 컴포넌트가 마운트 될 때 fetch로 서버에서 받아오는 데이터 값이 없어서 생기는 오류 해결 (1) | 2023.05.17 |
React / 토큰 유무에 따른 조건부 랜더링 / token undefined가 true로 인식되는 오류 해결 (0) | 2023.05.17 |
React/ part.3 Mock Data (0) | 2023.04.29 |