[React] ReactRouter 사용 시 dom 변경 감지 (replace)

yiwoojung·2023년 4월 30일
0

React

목록 보기
12/12
post-thumbnail

팀 프로젝트로 React를 사용해서 관리자 페이지를 만드는 중에, 레이아웃을 구현하는데 문제가 생겼다. 네비게이션을 로그인/회원가입 페이지에서는 보여주지 않고 나머지에서만 보여주게 구현했는데 문제는 라우팅 시, 보여지는 url은 변경됐지만 UI적으로는 변경된 부분이 없어서 그런지 새로고침을 해야 메인 페이지에서 네비게이션이 보이는 것이다.

수정 전 코드

App.tsx

function App() {
  return (
    <BrowserRouter>
      <Layout>
        <Routes>
          <Route path="/" element={<LoginPage />} />
          <Route path="/signup" element={<SignUpPage />} />
          <Route path="/signup_steps" element={<SignUpStepsPage />} />
          <Route path="/main" element={<MainPage />} />
          <Route path="/information" element={<InformationPage />} />
          <Route path="/reservation" element={<ReservationPage />} />
        </Routes>
      </Layout>
    </BrowserRouter>
  );
}

export default App;

회원가입 이후에 페이지 navigate 하는 부분

    <Link to={"/main"}>
      <button className="btn_submit">병원 정보 등록하기</button>
	</Link>

시도한 방법

1. Router가 중복 사용되었는지 확인한다.

Router를 중복으로 사용하게 되면 url 정보를 전달하지 못해서 문제가 발생할 수 있다고 한다. 하지만 나는 App.tsx에서만 라우터를 사용하고 있어서 이 문제는 아니라고 생각했다.

2. Router를 부모 컴포넌트에서 사용한다.

BrowserRouter를 App.tsx가 아닌 index.tsx에서 불러오는 방법이다.

const rootNode = document.getElementById('root');

ReactDOM.createRoot(rootNode).render(
    <BrowserRouter>
      <React.StrictMode>
        <App/>
      </React.StrictMode>
    </BrowserRouter>
);

기존 App.tsx의 BrowserRouter는 Fragment tag(<></>)를 사용해서 감싸준다.

다른 분 블로그를 보니까 이 방법으로 해결을 했다고 하셨는데 내 경우는 왜인지 그대로였다.

3. react-router-dom 버전 맞추고 useHistory => useNavigate로 변경한다.

이 블로그에서 소개하는 방식으로 해봤는데도 해결하지 못했다,,,,! history 라이브러리 사용하면서 react-router-dom과 버전 맞추고 useHistory => useNavigate으로 변경해서 해결했다고 하는 분들이 꽤 있는 것 같다. 나는 history랑 useHistory 둘다 사용하지 않기 때문에 이 문제는 아닌 것 같다.


🐝 해결한 방법

무작정 구글링만 해도 해결되지 않아서 힘들어하다 근본적으로 React Router 공식 홈페이지를 놓치고 있었다는 생각을 하게 되었다. 그리고 역시 공식 홈페이지를 통해 문제를 해결할 수 있었다.

Browser Router

우선 내 경우는 react-router의 BrowserRouter를 사용하였다. 그래서 브라우저에 내장된 history 스택을 사용중이었다. 다음은 공식 홈페이지에 나와있는 BrowserRouter 의 설명이다.

A stores the current location in the browser's address bar using clean URLs and navigates using the browser's built-in history stack.

Browser Router는 깨끗한 URL들을 사용하여 브라우저 주소창에 현재 위치를 저장하고 브라우저에 내장된 history 스택을 사용해서 navigate(페이지를 탐색)한다.

BrowserRouter 안에서 navigate을 하기 위해 Link 태그를 사용하고 있었는데 공홈을 잘 살펴보니 link 태그의 옵션 중에 replace 를 사용하면 해결할 수 있을 것 같았다.

replace (true || false)

replace: true 로 설정하면 브라우저 history 스택에 새 항목을 추가하지 않고 현재 항목으로 대체해준다고 한다.
일반적으로 브라우저의 뒤로 가기 버튼을 눌렀을 때, 이전 페이지로 이동하는 것이 아니라 현재 페이지를 바로 빠져나오고 싶을 때 사용할 수 있는 옵션이다.

그래서 나의 경우는 회원가입이나 로그인 후에 다시 메인페이지로 돌아가는 것이 아니라 새로운 메인페이지로 이동(실제로 dom이 변경됨을 감지하고 UI가 달라져야하는 시점)했다고 replace를 해주는 방법으로 문제를 해결하였다.

수정한 코드

회원가입 이후에 페이지 navigate 하는 부분

    <Link to={"/main"} replace>
      <button className="btn_submit">병원 정보 등록하기</button>
	</Link>

이걸 Link 태그 대신 useNavigate 을 사용해서 구현할 수도 있다.

  	const navigate = useNavigate();
    
    const moveToMainPage = () => {
      navigate("/main", { replace: true });
    };

해결책은 매우 간단한 것이었는데 많이 헤매고나니 앞으로 리액트에서 라우팅을 할 수 있는 여러가지 방법을 비교해보고 상황에 맞게 라우터를 구현해야겠다는 생각을 하게 되었다. 또 역시 해결책은 공식 홈페이지에 있다는 것을 새삼 느낄 수 있었던 하루였다...!

참고

profile
프론트엔드 개발자

0개의 댓글