클론 코딩 책을 보고 따라하던 중 기재된 내용과는 다르게 자꾸 에러가 나는 상황이 발생했다. 아무래도 책이다보니 출판 후 업데이트 되기가... ㅎㅎ
React-router가 v6로 업데이트 되어 생기는 에러가 대다수였다.
최신 뉴스는 아니었지만 그동안 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' 카테고리의 다른 글
[React.js] Function Component vs Class Component (0) | 2022.08.30 |
---|---|
import 중괄호 {}의 의미 (0) | 2022.08.25 |
React + Typescript (0) | 2022.05.10 |
[Error] ... is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment> (0) | 2022.02.22 |
[error] firebase 오류 - firebase import가 안됨 (0) | 2022.02.21 |