본문 바로가기
Web Development/React

React / useNavigate를 사용해서 경로 이동을 해야할 때 발생하는 페이지 공백 오류 해결

by Krystal K 2023. 5. 17.

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 페이지가 보여지게 된다.

 

 

최종 수정된 코드

728x90