React

React-Router V6로 업데이트 하면서 달라진 점

Bittersweet- 2022. 4. 29. 12:14
728x90

클론 코딩 책을 보고 따라하던 중 기재된 내용과는 다르게 자꾸 에러가 나는 상황이 발생했다. 아무래도 책이다보니 출판 후 업데이트 되기가... ㅎㅎ

React-routerv6로 업데이트 되어 생기는 에러가 대다수였다.

최신 뉴스는 아니었지만 그동안 React에 소홀했던 나에겐(반성반성😑 ) 당황스러웠다.

내용을 잊지 않기 위해 정리해본다.

 

Migration 프로세스

1. React V16.8 이상으로 업그레이드

    

2. React Router V5.1 이상으로 업그레이드

  • <Switch> 내부의 <Redirect> 모두 제거
  • <Route> 커스텀 리팩토링 - components나 render 속성을 사용하는 대신 children 속성 사용

3. React Router V6으로 업그레이드


V6버전은  V5버전 대비 번들 사이즈가 많이 줄었다고 한다. (이전 대비 70%정도의 크기가 줄었다고 함)

그렇기 때문에 Migration을 권고한다.

 

변경된 사항에 대해 알아보도록 하자.

Diff 1 . switch -> routes로 네이밍 변경

기존에 Route를 감싸는 부모요소인 Switch가 Routes로 변경되었다.

<Routes>
  <Route />
</Routes>

 

Diff 2. exact 옵션 삭제

모든 route의 기본값이 exact로 변경되었으므로 사용할 필요가 없다. 만약 하위 경로가 더 많은 url을 일치시키려면 *를 사용하여 매칭시킬 수 있다.

<Route path="member/*" />

 

Diff 3. StaticRouter의 import 위치 변경

import 패키지 경로가 변경되었다.

import { StaticRouter } from 'react-router-dom/server';

 

Diff 4. useHistory -> useNavigation

useHistory 훅이 useNavigation으로 변경되었다. 이 뿐 아니라 push, replace, goBack 등의 메소드로 동작하는 부분도 변경되었다.

state를 변경하는 부분은 뒤의 인자에 넣어주면 된다.

const navigate = useNavigate();

// push
navigate('/');

// replace
navigate('/', {state: {showLoginModal: true}, replace: true});

// goBack
navigate(-1);

 

Diff 5. Redirect 제거

V6에서는 Redirect 컴포넌트를 더이상 지원하지 않는다. Navigation 컴포넌트를 사용하여 마이그레이션을 진행한 수 replace 속성과 to="url"을 사용하여 리다이렉트를 설정할 수 있다.

// V5.1 이전
<Redirect from="/before" to="/after" />

// V5.1 업데이트
<Route path="/before" render={() => <Redirect to="/after" />} />

// V6
<Route path="/before" element={<Navigation replace to="/after" />} />

 

Diff 6. render -> element

이전에는 컴포넌트를 렌더링하기 위해 사용됐던 component 속성element 속성으로 변경되었으며 작성법 또한 JSX 방식으로 변경되었다.

<Route path="/" element={<Home />} />

 

Diff 7. 중첩라우팅

중첩 라우팅으로 하위에 있으면 자동 /로 구분되므로 추가적인 /를 path를 입력할 필요가 없어졌다.

//v5
<Switch>
  <Route path="/member" />
  <Route path="/member/:memberId" />
</Switch>

//v6
<Routes>
  <Route path="/member">
    <Route path=":memberId" /> // /member/:memberId
  </Route>
</Routes>

 

 

Diff 8. 중첩 영역 렌더링

중첩 영역 렌더링 요소에 Outlet 속성을 제공하면 된다.

// /mypage/setting 접근 시 Setting 컴포넌트가 렌더링 되는 예시
const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="mypage" element={<Mypage />}>
          <Route path="setting" element={<Setting />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
};

const Mypage = () => {
  return (
    <div>
      <Outlet />
    </div>
  );
};

 

Diff 9. Optional parameters 지원 중지

?를 붙여 parameter의 유무를 명시해주던 문법이 사라졌다. 그래도 이 부분은 중첩 Route를 사용해서 해결이 가능하다.

// V5
<Route path="/search/:keyword?" component={SearchPage} />

// V6
<Route path="/search" element={<SearchPage />}>
  <Route path=":keyword" element={<SearchPage />} />
</Route>

 

Diff 10. TypeScript Hook

TypeScript를 사용할 경우 방법이 변경되었다.

다른것도 많이 변경되었지만 useParams의 경우 아래의 예시를 참고하자

// 이전 버전
const { name } = useParams<{name: string}>( );

// V6
const { name } = useParams<'id'>();

 

이 밖에 바뀐점

위의 내용 외에도 useRoutes 등 변경된 점이 많다. 이외의 내용이 궁금하다면 아래의 공식문서를 확인해보기 바란다.

 

다만, 마이그레이션 시 소요되는 시간이 오래 걸리지는 않으나 전체적으로 프로젝트 진행과 함께 쌓아온 신뢰를 떨어뜨릴 수 있는 행동이라고 생각한다.

프로젝트 중반 마이그레이션을 시도할 경우, 충분히 검토해보고 진행하길 바란다.

 

 

https://reactrouter.com/docs/en/v6/upgrading/v5#upgrading-from-v5

 

React Router | Upgrading from v5

Declarative routing for React apps at any scale

reactrouter.com