1. BrowserRouter
react 프로젝트에 React Router를 적용할 때 React Router Dom
에 내장되어 있는 BrowserRouter
컴포넌트로 감싸준다.
이 컴포넌트는 Histroy API를 사용하지 않고도 url을 변경하고 현재 주소의 경로에 관련된 정보를 리액트 컴포넌트에서 사용할 수 있도록 도와준다.
1.1 Router.tsx
Route 컴포넌트를 통해 path
, element
를 지정해주고 url을 분기처리해준다.
Route 컴포넌트는 Routes
로 감싸줘야함.
// Router.tsx
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Header from "../Components/Header";
import About from "./About";
import Home from "./Home";
function Router() {
return (
<BrowserRouter>
<Header />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
export default Router;
1.2 Header.tsx
Header
에 Link
컴포넌트를 가져와서 to에 지정한 url로 페이지 라우터가 가능하도록 할 수 있다.
Link
컴포넌트도 BrowserRouter
내부에 위치해야한다.
// Header.tsx
import { Link } from "react-router-dom";
function Header() {
return (
<header>
<ul>
<li>
<Link to={"/"}>Home</Link>
</li>
<li>
<Link to={"/about"}>About</Link>
</li>
</ul>
</header>
);
}
export default Header;
2. createBrowserRouter
- React-Router-Dom 6.4에 새롭게 추가된 방식.
- Route를 중첩된 경로가 있는 객체의 배열로 나타낼 수 있다.
첫번째 Route
는 Root 컴포넌트로, 하위 라우터들의 부모와 같은 역할을 하며, Childern
값으로 라우트를 지정해주면
위와 같은 구조로 렌더링되게 만들 수 있다.
2.1 Router.tsx
import { createBrowserRouter } from "react-router-dom";
import Root from "./Root";
import About from "./screens/About";
import Home from "./screens/Home";
// Router를 array 형식으로 표현할 수 있다.
const Router = createBrowserRouter([
// 첫번째 Route는 전체 route들의 컨테이너와 같은 역할
{
path: "/",
element: <Root />,
children: [
// Root 컴포넌트 내에서 path에 따라 Home, About 컴포넌트를 렌더링 해주는 것
{ path: "", element: <Home /> },
{ path: "about", element: <About /> },
],
},
]);
export default Router;
2.2 Root.tsx
CreatBrowserRouter
에서 children을 지정해주려면 Outlet
컴포넌트를 꼭 렌더링해줘야 한다.
import React from "react";
import { Outlet } from "react-router-dom"; // router 컴포넌트에서 children 속성 사용하기 위함
function Root() {
return (
<div>
<Outlet />
</div>
);
}
export default Root;
2.3 Index.tsx
RouterProvider
로 위에서 만든 Router를 전달하여 렌더링 해준다.
import React from "react";
import ReactDOM from "react-dom/client";
import { RouterProvider } from "react-router-dom";
import Router from "./Router";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
{/* router props로 creteBrowserRouter로 만든 컴포넌트를 넘겨준다. */}
<RouterProvider router={Router} />
</React.StrictMode>
);
3. UseNavigate
Link 는 클릭시 페이지 이동이라면,
UseNavigate
훅을 통해서 로그인이나 특정 상태 변경시 사용자가 별다른 동작을 취하지 않아도 페이지 이동이 가능하다.
// Header.tsx
import { Link, useNavigate } from "react-router-dom";
function Header() {
const navigate = useNavigate();
const onAboutClick = () => {
navigate("/about");
};
return (
<header>
<ul>
<li>
<Link to={"/"}>Home</Link>
</li>
<li>
<button onClick={onAboutClick}>About</button>
</li>
</ul>
</header>
);
}
export default Header;
위에서는 버튼 클릭시 onClick 이벤트를 통해 useNavigate
훅을 실행했지만 로그인, 로그아웃 등 효율적으로 사용 가능할 것 같다.
4. UseParams
라우트 이동시 특정 파라미터를 넘겨준다면 UseParams
를 통해 가져와서 활용할 수 있다.
4.1 Router.tsx
컴포넌트를 userId 파라미터에 따라 다른 화면을 렌더링해줄 수 있다.
여기서 주의할 점은 만약 '/users' 로 접근하면 컴포넌트를 렌더링하게 된다.
'/users' 로 접근했을 때 보여줄 화면이 있다면,
{path : "users", element : , children : \[ .....\]}
이런식으로 구성할 수 있다.
const Router = createBrowserRouter([
// 첫번째 Route는 전체 route들의 컨테이너와 같은 역할
{
path: "/",
element: <Root />,
children: [
// Root 컴포넌트 내에서 path에 따라 Home, About 컴포넌트를 렌더링 해주는 것
{ path: "", element: <Home />, errorElement: <ErrorComponent /> },
{ path: "about", element: <About /> },
{ path: "users/:userId", element: <Users /> },
],
errorElement: <NotFound />,
},
]);
4.2 Users.tsx
useParams
를 통해 파라미터로 넘겨준 userId를 가져와서 사용할 수 있따.
import { useParams } from "react-router-dom";
import { users } from "../../db";
function Users() {
const { userId } = useParams();
return (
<h1>
User with it {userId} is named : {users[Number(userId) - 1].name}
</h1>
);
}
export default Users;
5. UseOutletContext
Outlet
컴포넌트로 컴포넌트 내에 하위 라우트를 children으로 지정하면서, context
props를 통해 하위 라우트와 공유할 상태나 값을 넘겨줄 수 있다.
하위 컴포넌트에서는 UseOutletContext
훅을 통해 넘겨준 값을 가져와서 사용할 수 있다.
5.1 Users.tsx
context로 이름을 넘겨준다.
import { Outlet, useParams, Link } from "react-router-dom";
import { users } from "../../db";
function Users() {
const { userId } = useParams();
return (
<div>
<h1>
User with it {userId} is named : {users[Number(userId) - 1].name}
</h1>
<hr />
<Link to="followers">See Followers</Link>
<Outlet context={{ nameOfMyUser: users[Number(userId) - 1].name }} />
</div>
);
}
5.2 Router.tsx
Users 컴포넌트의 하위 라우트 Followers 컴포넌트를 연결해준다.
import { createBrowserRouter } from "react-router-dom";
import ErrorComponent from "./Components/ErrorComponent";
import Root from "./Root";
import About from "./screens/About";
import Home from "./screens/Home";
import NotFound from "./screens/NotFound";
import Followers from "./screens/users/Followers";
import Users from "./screens/users/Users";
// Router를 array 형식으로 표현할 수 있다.
const Router = createBrowserRouter([
// 첫번째 Route는 전체 route들의 컨테이너와 같은 역할
{
path: "/",
element: <Root />,
children: [
{ path: "", element: <Home />, errorElement: <ErrorComponent /> },
{ path: "about", element: <About /> },
{
path: "users/:userId",
element: <Users />,
children: [{ path: "followers", element: <Followers /> }],
},
],
errorElement: <NotFound />,
},
]);
export default Router;
5.3 Followers.tsx
useOutletContext
를 통해 위에서 상위 컴포넌트인 Users에서 Context
를 통해 넘겨준 이름 값을 가져와서 사용해줄 수 있다.
import { useOutletContext } from "react-router-dom";
interface IFollowersContext {
nameOfMyUser: string;
}
function Followers() {
const { nameOfMyUser } = useOutletContext<IFollowersContext>();
return <h1>Here are {nameOfMyUser}의 Followers</h1>;
}
export default Followers;
'Frontend > React' 카테고리의 다른 글
[React] React Query 톺아보기 (0) | 2023.07.25 |
---|---|
[React] Styledcomponents S-dot naming (1) | 2023.07.05 |
[React] Typescript + Inline style (1) | 2023.07.05 |
[React] Context API (1) | 2023.07.03 |
[React] CSS Reset (2) | 2023.01.08 |