일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- ASP.NET
- JSBridge
- JUNCTION2023
- 코드트리
- useState
- 개발자 원칙
- framer
- CSS
- 알고리즘
- 타입스크립트
- typescript
- Effective Typescript
- react
- TS
- Framer motion
- VS Code
- framer-motion
- 테오의 스프린트
- 개발자를 위한 글쓰기 가이드
- Semantic Versioning
- 글또
- React-Router-Dom
- 캐나다취준
- CSS방법론
- 이펙티브타입스크립트
- SemVer
- 글또 10기
- 시스템디자인
- 회고
- 캐나다개발자
- Today
- Total
큰 꿈은 파편이 크다!!⚡️
react router dom6 적용하기 본문
React를 사용한다면 아주 익숙할 React Router가 2020년 12월에 v6을 릴리스했다. 메이저 버전넘버가 바뀐 만큼 breaking-changes가 있었고, 그동안 무지성으로 이 패키지를 사용했고 공식문서에 소홀했던 것을 반성하며 v5에서 v6으로 넘어가면서 알게 된 몇가지 내용을 정리해보려 한다.
🐓 react-router-dom을 뭣모르고 사용했더니 일어난 일
react-router-dom
vs react-router-native
$ npm install react-router-dom
# or, for a React Native app
$ npm install react-router-native
웹 개발을 위해 react를 사용한다면 react-router-dom
을 설치한다. 위 코드에서 알 수 있듯 react-router-native
는 react native를 위한 패키지이다.
react-router
vs react-router-dom
import { Link } from "react-router"
import { Link } from "react-router-dom"
위 두가지 import방법의 결과는 동일하다. 그렇다고 아무거나 쓰면 나같은 닭대가리가 된다.
react-router = dom + native라고 볼 수 있다. 즉, 우리는 웹 개발에 필요한 게 다 들어있는 dom만 사용하면 되지 굳이 native의 내용까지 포함하고 있는 react-router
를 import할 필요가 없다.
📈 v5 -> v6 가즈아
이제 기존에 사용하던 v5를 v6으로 올리는 작업에 착수한다.
모든 내용은 공식문서에서 더 자세히, 더 많이 확인할 수 있다. 이 글을 작성하면서 공식문서를 보는 연습을 할 수 있었다.
Switch
바로 아래에 있는 Redirect
삭제
현재(v5) 기준으로 약간의 밑작업을 한다. Switch
바로 아래에 있는 Redirect
는 삭제한다.Switch
아래 아래에 있는 Redirect
는 둬도 상관없다. 어차피 나중에 Redirect
자체가 없어질 예정이다^^
// Change this:
<Switch>
<Redirect from="about" to="about-us" />
</Switch>
// to this:
<Switch>
<Route path="about" render={() => <Redirect to="about-us" />} />
</Switch>
PrivateRoute 리팩토링
로그인된 사용자만 접근 가능한 페이지, 등을 만들 때 custom하게 만드는 Route
를 Protected Route, Private Route 라고 한다. 이런 Plain Route
가 아닌 것들을 Switch 아래에서 일단 제거한다.
드디어 v6으로 패키지 업데이트
를 하기 전에 선행되어야 할 작업이 있다. 사용중인 react의 버전이 v16.8이상인지 확인하고, 미만이라면 react버전을 먼저 맞게 업데이트하기!
yarn upgrade react-router-dom --latest
나는 yarn을 사용하기 때문에 최신 패키지로 업데이트하는 명령어를 사용했다.
Switch
-> Routers
Switch가 Routers
로 바뀌었고, exact가 삭제되었다. (이름이 바뀐 것이 꽤 많은데, 흐름, 가독성 등을 고려해서 변경한 것이라고 함!) Routers
안에 Router
가 있으니 편-안하다.
function AppV5() {
return (
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
</Switch>
);
}
function AppV6() {
return (
<Routers> // 😮
<Route path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
</Routers>
);
}
Route
의 변경사항
Route에 children을 넣어주는 방식이 element를 넣어주도록 바뀌었다.
· Element: DOM 노드를 나타내는 객체
· Component: Input을 받고 element를 반환하는 함수/클래스
결과적으로 해당 컴포넌트에 props를 전달하기 편리해졌고,
기존에 있던 <Route children>
은 v3에서 제공했던 nesting routes를 사용할 수 있는 예약어가 되었다.
function AppV5() {
return (
<Switch>
<Route exact path="/" component={ Home } />
<Route path=":userId" component={Profile} passProps={{ animate: true }} />
<Route
path=":schoolId"
render={routeProps => (
<School routeProps={routeProps} animate={true} />
)}
/>
</Switch>
);
}
//V6
function AppV6() {
return (
<Routers>
<Route path="/" element={ <Home/> } /> // 😮
<Route path=":userId" element={<Profile animate={true} />} />
<Route path=":schoolId" element={<School animate={true} />} />
<Route path="users" element={<Users />}>
<Route path="me" element={<OwnUserProfile />} /> // nested😮
<Route path=":id" element={<UserProfile />} />
</Route>
</Routers>
);
}
nested route를 사용하는 경우에는 <Outlet />
을 사용해서 child route를 렌더링해줄 수 있다.
function Users() {
return (
<div>
<nav>
<Link to="me">My Profile</Link>
</nav>
<Outlet />
</div>
);
}
<Route path>
를 정하는 방법도 간소화되었다. 현재 v6에서는 다이나믹 라우팅 (:id
) 스타일과, path의 마지막에만 사용할 수 있는 와일드카드 (*
)만을 제공한다. 기존에 regex를 사용해서 id값을 숫자로 고정시킨다던가.. 하는 방식은 더이상 쓸 수 없다🥲 please know that we plan to add some more advanced param validation in v6 at some point 라고 하니 기다려봐야겠다.
//👍 All of the following are valid route paths in v6:
/groups
/groups/admin
/users/:id
/users/:id/messages
/files/*
/files/:id/*
//👎 The following RegExp-style route paths are not valid in v6:
/users/:id?
/tweets/:id(\d+)
/files/*/cat.jpg
/files-*
useHistory
대신 useNavigate
이건 단순히 이름 뿐만 아니라 사용 방법도 조금 바뀌었다.
//from this:
let history = useHistory();
function handleClick() {
history.push("/home");
}
//to this:
let navigate = useNavigate();
function handleClick() {
navigate("/home"); //여기까진 👍
}
만약 state를 같이 전달한다면?
//from this:
let history = useHistory();
function handleClick() {
history.push({
path: "/home",
state: { name: "John" }
});
}
//to this:
let navigate = useNavigate();
function handleClick() {
navigate("/home", { //😮
state: { name: "John" }
});
}
go, goback, goforward등은 어떻게? navigate로 전부 해결한다.
//from this:
<button onClick={goBack}>Go back</button>
<button onClick={goForward}>Go forward</button>
<button onClick={() => go(2)}>Go 2 pages forward</button>
//to this: 😮
<button onClick={() => navigate(-1)}>Go back</button>
<button onClick={() => navigate(1)}>Go forward</button>
<button onClick={() => navigate(2)}>Go 2 pages forward</button>
Redirect
-> Navigate
Redirect
를 삭제할 차례다. Redirect
의 default는 replace였고 Navigate
의 default는 push이기 때문에 적절하게 교차해서 바꿔준다.
· replace: stack top의 페이지를 교체한다.
· push: stack top에 페이지를 쌓는다.
// Change this:
<Redirect to="about" />
<Redirect to="home" push />
// to this:
<Navigate to="about" replace />
<Navigate to="home" />
Link
개선
v5에서는 현재 URL이 /users일 때, <Link to="me">
-> <a href="/me">
를 렌더링했고,
현재 URL이 /users/일 때(=trailing slash를 포함할 때)는, <Link to="me">
-> <a href="/users/me">
를 렌더링해서 혼란스러운 경우가 있었다.
v6에서는 이 문제가 개선되어 현재 url의 trailing slash와 관계없이 항상 <Link to="me">
-> <a href="/me">
를 렌더링한다.
또한 ".."와 같은 상대 URL을 지원한다. 단, <Route path>
가 하나 이상의 segment와 매칭될 때에는 모든 segment를 제거하고 부모의 route path를 따를 것이다.
function App() {
return (
<Routes>
<Route path="users">
<Route
path=":id/messages"
element={
// This links to /users
<Link to=".." />
}
/>
</Route>
</Routes>
);
}
🙀 맺으며
· 너무 많기도 하고 내가 사용하지 않는 기능 (config)도 있어서 모든 변경사항을 담지는 않았다! 하지만 path match등 메인 페이지에 언급되지 않은 내용들도 변경된 것으로 보아 버전업을 진행하면서 맞추어나가야 할 것으로 보인다.
· 이번 기회를 통해 몰랐던 단어, 차이점 등의 내용도 정리할 수 있어 의미있었다.
· 근데 이거 코드블럭 언어가 왜이럴까.. 다른 방안을 찾아봐야겠다 ㅠㅠ;
'Web FE' 카테고리의 다른 글
🔨 웹에서 RTSP 스트리밍 + video autoplay 삽질기 (0) | 2022.07.23 |
---|---|
🍪 쿠키와 세션 (feat. 웹에서 로그인을 유지하는 원리) (0) | 2022.07.09 |
예제로 이해하는 React Custom Hook (0) | 2022.06.25 |
Framer motion 순한맛 찍먹 (0) | 2022.05.29 |
setState가 비동기인 이유? (0) | 2021.09.23 |