3. Router
1. RouterProvider
React Router ๋ฒ์ 6.4๋ถํฐ ์ง์ํ๋, ๋ผ์ฐํฐ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ์ฐ๋ ๋ฐฉ๋ฒ ๋ชจ๋ ๋ฐ์ดํฐ ๋ผ์ฐํฐ ๊ฐ์ฒด๋ ์ด ๊ตฌ์ฑ ์์๋ก ์ ๋ฌ๋์ด ์ฑ์ ๋ ๋๋งํ๊ณ ๋๋จธ์ง ๋ฐ์ดํฐ API๋ฅผ ํ์ฑํ
โ๏ธ ์กฐ๊ฐ๊ธ
React Router๊ฐ
Context API๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
๋ผ๋ ๊ฒ์ด ๋ฌผ์ฌ ๋๊ปด์ง๋ ํํธ์๋ค. Context API๋ฅผ ์ฌ์ฉํด๋ณธ ์ ์ด ๋ง์ง ์์์ ๊ทธ๋ฐ์ง, '๊ตณ์ด RouterProvider๋ฅผ ์ฌ์ฉํด ๋ผ์ฐํ ์ ๊ตฌํํด์ผ ํ ๊น?'๋ผ๋ ์๋ฌธ์ด ๋ ๋ค. 2๊ฐ์์ ๋ฐฐ์ ๋ ๊ธฐ์กด์ ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ฉด ์ด๋ ์๊ฐ ๋ถํธํด์ง๋ ์ผ์ด ์๊ธฐ๊ธฐ ๋๋ฌธ์ผ๊น? ํ์ด์ง๊ฐ ๋ง์ด ๋์ค์ง ์๋ ์์ ํ๋ก์ ํธ๊ฐ์ ๊ฒฝ์ฐ์๋ ๊ทธ๋ฅ ์ด์ ๋ฐฉ์์ ์ฌ์ฉํ์๋๋ฐ, ์ฐ์ต ์ฐจ์์์ RouterProvider๋ ์ฌ์ฉํด ๋ด์ผ๊ฒ ๋ค.
2. createBrowserRouter
React Router ์น ํ๋ก์ ํธ์ ๊ถ์ฅ๋๋ ๋ผ์ฐํฐ DOM History API๋ฅผ ์ฌ์ฉํ์ฌ URL์ ์ ๋ฐ์ดํธํ๊ณ ๊ธฐ๋ก ์คํ์ ๊ด๋ฆฌ loaders, actions, fetchers ๋ฑ๊ณผ ๊ฐ์ v6.4 ๋ฐ์ดํฐ API๋ฅผ ํ์ฑํ
routes
children ํ๋กํผํฐ์ ์ค์ฒฉ๋ ๊ฒฝ๋ก๊ฐ ์๋ Route ๊ฐ์ฒด์ ๋ฐฐ์ด
createBrowserRouter([
{
path: "/",
element: <Root />,
loader: rootLoader,
children: [
{
path: "events/:id",
element: <Event />,
loader: eventLoader,
},
],
},
]);
3. ์ฌ์ฉ ๋ฐฉ๋ฒ
๐
App.tsx
๊ฐ ํ๋ ์ผ
์ ์ฒด์ ์ธ ๋ ์ด์์ ๊ตฌ์ฑ
๋ผ์ฐํ ๊ตฌ์ฑ
๋ผ์ฐํ
์ ๋ณด ๋ณ๋์ ํ์ผ๋ก ๋ถ๋ฆฌ
์ปดํฌ๋ํธ ๋ ์ด์์ ์ก๊ธฐ
// src/components/Layout.tsx
import Header from './Header';
import Footer from './Footer';
import { Outlet } from 'react-router-dom';
export default function Layout() {
return (
<div>
<Header/>
<Outlet/>
<Footer/>
</div>
);
}
๋ ์ด์์ ์ ์ฉ
๐ก ํ ์คํธ์์๋ routes ์ ๋ณด๋ฅผ ํ์๋ก ํ๊ธฐ ๋๋ฌธ์, ํ ์คํธ๋ฅผ ํธ๋ฆฌํ๊ฒ ํ๊ธฐ ์ํด ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ข์
// src/routes.tsx
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
import Layout from './components/Layout';
const routes = [
{
element: <Layout/>,
children: [
{path: '/', element: <HomePage/>},
{path: '/about', element: <AboutPage/>},
],
},
];
export default routes;
App.tsx
์์ ๋ถ๋ฌ์ค๊ธฐ
App.tsx
์์ ๋ถ๋ฌ์ค๊ธฐ๐จ RouterProvider์ BrowserRouter๋ฅผ ๋์์ ์ธ ๊ฒฝ์ฐ ์๋ฌ ๋ฉ์์ง
caught Error: You cannot render a
<Router>
inside another<Router>
. You should never have more than one in your app.
// src/App.tsx
import {createBrowserRouter, RouterProvider} from 'react-router-dom';
import routes from './routes';
const router = createBrowserRouter(routes);
export default function App() {
return (
<RouterProvider router={router}/>
);
}
๐ก App ์ปดํฌ๋ํธ๋ฅผ ๊ฑฐ์น์ง ์๊ณ ๋ฐ๋ก ๋ธ๋ผ์ฐ์ ๋ผ์ฐํฐ๋ฅผ ๋ง๋ค์ด์ ์ฌ์ฉํด๋ ๋จ
// src/main.tsx
import {createBrowserRouter, RouterProvider} from 'react-router-dom';
import routes from './routes';
const router = createBrowserRouter(routes);
root.render((
<React.StrictMode>
<RouterProvider router={router}/>
</React.StrictMode>
));
4. createMemoryRouter
App.tsx๋ฅผ ํ
์คํธํ๋ ๊ฒ์ ๋งค์ฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์, routes.test.tsx
๋ก ๋ณ๊ฒฝ
routes๊ฐ ๋ผ์ฐํ
์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์
createMemoryRouter๋ ๋ธ๋ผ์ฐ์ ์ ๊ธฐ๋ก์ ์ฌ์ฉํ๋ ๋์ ๋ฉ๋ชจ๋ฆฌ ๋ผ์ฐํฐ๋ ๋ฉ๋ชจ๋ฆฌ์์ ์์ฒด ๊ธฐ๋ก ์คํ์ ๊ด๋ฆฌ Storybook๊ณผ ๊ฐ์ ํ ์คํธ ๋ฐ ์ปดํฌ๋ํธ ๊ฐ๋ฐ ๋๊ตฌ์ ์ฃผ๋ก ์ ์ฉํ์ง๋ง, ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ ๋ชจ๋ ํ๊ฒฝ์์ React Router๋ฅผ ์คํํ๋ ๋ฐ์๋ ์ฌ์ฉํ ์ ์์
ํ
์คํธ ์ฝ๋ ์์ฑ
๋ฉ๋ชจ๋ฆฌ ๋ผ์ฐํฐ ๋ง๋ค์ด์ ํ ์คํธ
describe('routes', () => {
function renderRouter(path: string) {
const router = createMemoryRouter(routes, {initialEntries: [path]});
render(<RouterProvider router={router}/>);
}
context('when the current path is โ/โ', () => {
it('renders the home page', () => {
renderRouter('/');
screen.getByText(/Hello/);
});
});
context('when the current path is โ/aboutโ', () => {
it('renders the about page', () => {
renderRouter('/about');
screen.getByText(/About/);
});
});
});
Last updated