2022.10.04.
TILTIL
어제와 오늘 React Router에 대해서 학습했습니다. v5로 미니 프로젝트를 구현해보고 현재 가장 최신버전인 v6으로 마이그레이션을 하였습니다. v5에서 v6으로 변경된 점들을 기록합니다.
Route
v5
function App() {
return (
<Layout>
<Switch>
<Route path="/" exact>
<Redirect to="/quotes" />
</Route>
<Route path="/quotes" exact>
<AllQuotes />
</Route>
<Route path="/quotes/:quoteId">
<QuoteDetail />
</Route>
<Route path="/new-quote">
<NewQuote />
</Route>
<Route path="*">
<NotFound />
</Route>
</Switch>
</Layout>
);
}
v6
function App() {
return (
<Layout>
<Routes>
<Route path="/" element={<Navigate replace to="/quotes" />} /> // Redirect
<Route path="/quotes" element={<AllQuotes />} />
<Route path="/quotes/:quoteId" element={<QuoteDetail />} />
<Route path="/new-quote" element={<NewQuote />} />
<Route path="*" element={<NotFound />} />
</Routes>
</Layout>
);
}
- 전체 화면을 바꿔주는 Switch 태그가 Route 태그로 대체되었습니다.
- Route의 element 태그 추가되었습니다.
- Redirect가 사라지고 Route 태그와 Navigate 태그의 혼합형으로 대체되었습니다.
NavLink activeClassName
v5
const MainNavigation = () => {
return (
<ul>
<li>
<NavLink activeClassName={classes.active} to="/">
All Quote
</NavLink>
</li>
<li>
<NavLink activeClassName={classes.active} to="/new-quote">
Add a Quote
</NavLink>
</li>
</ul>
);
};
v6
const MainNavigation = () => {
return (
<ul>
<li>
<NavLink
className={navData => (navData.isActive ? classes.active : '')}
to="/"
>
All Quote
</NavLink>
</li>
<li>
<NavLink
className={navData => (navData.isActive ? classes.active : '')}
to="/new-quote"
>
Add a Quote
</NavLink>
</li>
</ul>
);
};
- NavLink는 그대로이나, activeClassName props가 없어졌습니다.
useHistory → useNavigate
v5
import { useHistory } from 'react-router-dom';
const NewQuote = () => {
const history = useHistory();
useEffect(() => {
if (status === 'completed') {
history.push('/quotes');
}
}, [status, history]);
// ...
};
v6
import { useNavigate } from 'react-router-dom';
const NewQuote = () => {
const { sendRequest, status } = useHttp(addQuote);
const navigate = useNavigate();
useEffect(() => {
if (status === 'completed') {
navigate('/quotes');
}
}, [status, navigate]);
// ...
};
- 페이지 이동 시, 사용하던 useHistory가 useNavigate로 대체되었습니다.
중첩 Route
v5
import { Fragment, useEffect } from 'react';
import { useParams, Link, Route, useRouteMatch } from 'react-router-dom';
const QuoteDetail = () => {
const match = useRouteMatch();
return (
<Fragment>
<HighlightedQuote text={loadedQuotes.text} author={loadedQuotes.author} />
<Route path={match.path} exact>
<div className="centered">
<Link className="btn--flat" to={`${match.url}/comments`}>
Load Comments
</Link>
</div>
</Route>
<Route path={`${match.path}/comments`}>
<Comments />
</Route>
</Fragment>
);
};
// app.js
<Route path="/quotes/:quoteId" element={<QuoteDetail />} />;
v6
import { Fragment, useEffect } from 'react';
import { useParams, Outlet } from 'react-router-dom';
const QuoteDetail = () => {
return (
<Fragment>
<HighlightedQuote text={loadedQuotes.text} author={loadedQuotes.author} />
<Outlet />
</Fragment>
);
};
// app.js
import { Route, Routes, Navigate, Link } from 'react-router-dom';
function App() {
return (
<Layout>
<Routes>
<Route path="/quotes/:quoteId" element={<QuoteDetail />}>
<Route
path=""
element={
<div className="centered">
<Link className="btn--flat" to={`comments`}>
Load Comments
</Link>
</div>
}
/>
<Route path={`comments`} element={<Comments />} />
</Route>
</Routes>
</Layout>
);
}
export default App;
- useRouteMatch가 사라지고 상대경로를 사용할 수 있게 되었습니다.
Prompt
v5
import { Prompt } from 'react-router-dom';
const QuoteForm = props => {
return (
<Fragment>
<Prompt
when={isEntering}
message={location =>
'Are you sure you want to lewave? All your entered data will be lost!'
}
/>
</Fragment>
);
};
- Prompt가 사라졌습니다.
이렇게 마이그레이션 한 내용들을 정리했습니다. 물론 더 많은 변경사항과 아직 알지 못하는 기능들이 있을텐데 그건 추후에 필요할 때 스터디하도록 하겠습니다.