react 18 + react-dom-router v5 호환 문제 해결 - url은 변경되는데 페이지는 새로 그리지 않는 문제

sumi-0011·2024년 10월 4일
0

🔥 트러블슈팅

목록 보기
13/13

문제 상황 👿

React 17에서 18로 버전을 업그레이드하면서 예상치 못한 라우팅 문제가 발생했습니다.
프로젝트에서 react-router-dom v5.3.4를 사용 중이었는데, 특정 페이지에서 뒤로가기 기능이 제대로 작동하지 않는 현상이 나타났습니다.
단순히 뒤로가기가 안되는것은 아니였고, 다른 페이지로의 이동에서도 동일한 현상이 발생하는 상황이었습니다.

밑과 같이 url은 정상적으로 변경되는데 새로 렌더링되지 않아, 화면에는 여전히 이전 페이지의 내용이 표시되는 것이 문제였어요.

http://localhost:3000/history/detail -> http://localhost:3000/history

원인 분석 🤔

문제의 원인을 찾기 위해 여러 자료를 찾아본 결과, React 18과 react-router-dom v5의 조합에서 React.StrictMode가 문제를 일으키고 있다는 알게되었고,
React 18에서는 StrictMode의 동작이 변경되면서 이로 인해 react-router-dom v5와 호환성 문제가 발생한 것으로 확인하였습니다.

issue의 답변중 아래와 같은 답변이 있습니다.

Just to clarify the issue: with React 18 StrictMode, react-router does not perform the transition when navigation occurs. The route is stale when the path is changed: codesandbox.io/s/dreamy-andras-hbuco1?file=/src/index.tsx

참고한 이슈

fyi) react-router-dom v5.3.3 이상에서는 이 문제가 해결되었다고 알려져 있었지만, 실제로 v5.3.4를 사용 중임에도 같은 문제가 발생하였습니다 관련 PR

해결 방법 💡

이슈를 확인해보았을 때 해결 방법으로는 아래 두 방법을 확인하였습니다.
1. react-router-dom을 v6로 업그레이드
2. React.StrictMode의 위치를 BrowserRouter 내부로 이동

저는 프로젝트의 규모와 복잡도를 고려했을 때, v6로의 업그레이드는 상당한 작업량이 필요할 것으로 예상되어 2번 방법을 선택하였습니다.

🔍 react-router-dom v6로 업그레이드를 고려 중이라면, React Router의 공식 업그레이드 가이드를 참고하는 것이 좋을 것 같아요

코드 수정 🛠️

문제 해결을 위해 React.StrictModeBrowserRouter의 위치를 다음과 같이 변경했습니다.

변경 전:

<React.StrictMode>
  <BrowserRouter>
    {/* ... */}
  </BrowserRouter>
</React.StrictMode>

변경 후:

<BrowserRouter>
  <React.StrictMode>
    {/* ... */}
  </React.StrictMode>
</BrowserRouter>

구체적인 코드 변경 내용은 다음과 같습니다

변경 전 (/src/index.tsx):

const container: Element = document.getElementById('root') as Element;
const root = createRoot(container);

root.render(
  <>
    <React.StrictMode>
      <Suspense fallback={<div></div>}>
        <MypageApp /> {/* 내부에 BrowserRouter 존재 */}
      </Suspense>
    </React.StrictMode>
  </>
);

변경 후 (/src/index.tsx):

const container: Element = document.getElementById('root') as Element;
const root = createRoot(container);

root.render(
  <>
    <BrowserRouter>
      <React.StrictMode>
        <Suspense fallback={<div></div>}>
          <MypageApp />
        </Suspense>
      </React.StrictMode>
    </BrowserRouter>
  </>
);

결론 📄

React 18로의 마이그레이션 과정에서 예상치 못한 라우팅 문제가 발생했지만, React.StrictModeBrowserRouter의 위치를 조정하는 간단한 방법으로 해결할 수 있었어요.

하지만 위와 같은 방법을 사용하는 것은 임시 방편일 뿐, 장기적으로 보면은 react-router-dom v6로 마이그레이션 하는것이 가장 좋은 해결책일 것 같습니다 🥲

React Router Issue에서도 관련 내용이 존재합니다.

profile
안녕하세요 😚

0개의 댓글