패키지 설치
yarn add react-router-dom
사용 순서
페이지 컴포넌트 생성
pages 폴더 내에 .jsx 파일들 생성해줌
- Home.jsx
- About.jsx
- Works.jsx
- Contact.jsx
scr > shared 폴더에 Router.jsx 파일 생성
const { BrowserRouter } = require("react-router-dom");
const Router = () => {
return <BrowserRouter></BrowserRouter>;
};
export default Router;
BrowserRouter > Routes > 여러 Route들 의 계층구조로 만든다
- 이 Route 들을 이동할 수 있는 SPA를 만드는 것!
Route는 두개의 props를 받는다
- path: 프로젝트에서 사용할 경로
- element: 표시할 컴포넌트
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "../pages/Home";
import About from "../pages/About";
import Contact from "../pages/Contact";
import Works from "../pages/Works";
const Router = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
<Route path="/works" element={<Works />} />
</Routes>
</BrowserRouter>
);
};
export default Router;
App.js에 import 및 적용
Router.jsx에서 Router import! react-router-dom의 Router import 하지 않도록 주의
import Router from "./shared/Router";
function App() {
return (
<>
<Router />
</>
);
}
export default App;
페이지 이동 확인
실행시켜보면 기본경로에서 Home, 기본경로/about에서 About 등 경로에 맞는 컴포넌트가 보이는 것을 확인할 수 있다!
react-router-dom hooks
useNavigate
특정 페이지로의 이동을 구현하는 훅
import { useNavigate } from "react-router-dom";
const Home = () => {
const navigate = useNavigate();
return (
<div>
<div>Home</div>
<button onClick={() => navigate("/works")}>Works로 이동</button>
</div>
);
};
export default Home;
useLocation
react-router-dom을 사용하면 현재 위치하고 있는 페이지의 여러가지 정보를 추가적으로 얻을 수 있음
이 정보들을 이용해 페이지 안에서 조건부 렌더링을 활용할 수 있음
import { useNavigate, useLocation } from "react-router-dom";
const Works = () => {
const location = useLocation();
console.log(location);
};
useLocation으로 받아온 location을 console.log로 출력해보면 아래와같이 객체 형태로 값이 저장돼있음을 확인할 수 있다
따라서 location.pathname.slice(1) 등으로 경로 정보를 활용할 수 있다
Link 태그
.jsx에서 a태그를 사용하고 싶은 경우 Link 태그를 사용한다.
(a태그는 새로고침하며 이동 -> SPA 아님)
import Link from 'react-router-dom';
<Link to="/contact">Contact 페이지로 이동하기</Link>
children 활용해 레이아웃 만들기
router 기능으로 다른 path들로 이동하면서, 공통적으로 필요한 layout이 있을 수 있다.
1. Routes 전체를 감싸는 Layout 컴포넌트 생성
2. Layout 컴포넌트는 children을 받아 내부 요소를 구성함
function Layout({children}) {
return (
<div>
<Header/>
<div style={{...layoutStyles}}>{children}</div>
<Footer/>
</div>
)
}
이렇게하면 틀 안에서 보여지는 컴포넌트들을 바꿔가며 사용할 수 있다!
Dynamic routing (동적 라우팅)
path에 유동적인 값을 넣어서 특정 페이지로 이동하게 하는 것
방법
<Route/>의 path에 :속성을 넣어준다
<Route path="works/:id" elements={<Works/>} />
그럼 기본적으로 Works 컴포넌트지만 id에 따라 다른 값을 보여주도록 활용할 수 있다!
const Router = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
<Route path="/works" element={<Works />} />
<Route path="/works/:id" element={<Works />} />
</Routes>
</BrowserRouter>
);
};
const Works = () => {
const data = [
{ id: 1, todo: "리액트 배우기" },
{ id: 2, todo: "운동하기" },
{ id: 3, todo: "또띠아 해먹기" },
];
return (
<div>
<div>Works</div>
{data.map((work) => {
return (
<div key={work.id}>
<div>할 일: {work.id}</div>
<Link to={`/works/${work.id}`}>"{work.todo}"로 이동</Link>
</div>
);
})}
</div>
);
};
export default Works;
useParams hook
동적 라우팅으로 전달받은 다른 속성값을 변수로 받아 활용할 수 있다.
useParams()로 반환받은 객체는 동적라우팅으로 전달받은 값을 갖고있다
key가 id인 이유는 동적라우팅에서 지정한 값이 :id였기 때문!
const Works = () => {
const param = useParams();
const data = [
{ id: 1, todo: "리액트 배우기" },
{ id: 2, todo: "운동하기" },
{ id: 3, todo: "또띠아 해먹기" },
];
const targetWork = data.find((work) => work.id === Number(param.id));
// 생략
}
이와같이 활용해 works 컴포넌트 중에서도 어떤 추가적인 패스를 전달받아 왔는지, 그리고 그 정보를 활용해 필요한 값을 얻을 수 있다
param으로 받는 값은 문자열이기 때문에 비교할 때 경우에따라 형변환이 필요할 수 있다.
return (
<div>
<div>Works</div>
<div>현재 페이지는 {targetWork.todo}입니다.</div>
// 생략
</div>
)
중첩된 라우트 Oulet
중첩 라우팅
특정 라우트 내에서 추가적인 라우트를 정의하는 방식
웹 애플리케이션에서 여러 계층의 UI를 구성할 때 유용하게 사용됨
예를들어, 사용자 대시보드에 여러 섹션이 있는 경우 섹션 별로 다른 경로를 설정할 수 있음
예제
1. DashBoardLayout.jsx 생성
function DashBoardLayout() {
return <div>DashBoardLayout</div>;
}
export default DashBoardLayout;
2. Route 지정
const Router = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
<Route path="/works" element={<Works />} />
<Route path="/works/:id" element={<Works />} />
<Route path="/dashboard" element={<DashBoardLayout />} />
</Routes>
</BrowserRouter>
);
};
이 dashboard 아래로 마이페이지도 있고, 좋아요한 목록도 있고 다양하게 존재했으면 좋겠음
3. MyPage 컴포넌트 생성하고 dashboard Route의 children으로 Route 생성
<Route path="/dashboard" element={<DashBoardLayout />}>
<Route path="mypage" element={<MyPage />} />
</Route>
4. outlet 사용
지금 단계까지의 상태에서 /dashboard/mypage로 들어가면 대시보드 컴포넌트 내용만 보인다.
이를 해결하기 위해 outlet이 필요함 (DashBoardLayout에서 사용)
import { Outlet } from "react-router-dom";
function DashBoardLayout() {
return (
<div>
<h1>DashBoardLayout</h1>
<Outlet />
</div>
);
}
export default DashBoardLayout;
대시보드에 또다른 중첩된 path가 추가된다면?
이동한 경로에따라 해당하는 하위 경로의 컴포넌트를 보여준다
Layout과의 차이?
레이아웃은 무조건 전체적인 스타일을 지정할 때 사용 가능함
DashBoard의 아래에 다양한 케이스를 추가하고 싶은 경우에는 outlet을 활용하는 것이 더 적합
'React' 카테고리의 다른 글
[React] redux, payload, ducks 패턴 (0) | 2024.08.20 |
---|---|
[React + Supabase] 설치, 셋팅, 간단한 사용법 (0) | 2024.08.20 |
[React] Effect가 필요하지 않을 수도 있습니다 (0) | 2024.08.18 |
[React] useSyncExternalStore (0) | 2024.08.18 |
[React] memoization (0) | 2024.08.17 |