참고
React Router
NOTE
Routing이란 요청한 URL에 따라 해당 URL에 맞는 페이지를 보여주는 개념이다.
리액트 라우팅의 예시
npm install react-router-dom
JavaScript
복사
설치 코드
사용자가 입력한 주소를 감지하는 역할을 하며, 여러 환경에서 동작할 수 있도록 여러 종류의 라우터 컴포넌트를 제공한다.
•
HashRouter: URL의 해시값을 이용하는 라우터
•
BrowserRouter: history API를 이용한다. (앞으로 사용할 라우터!)
Router 모듈(BrowserRouter, Route, Routes)
NOTE
import { BrowserRouter, Route, Routes } from 'react-router-dom';
const App = () => ( // path는 다양한 속성을 사용할 수 있다.
// :name(동적 세그먼트)
// ?(선택 사항)
// * 전체
<BrowserRouter>
<Routes>
<Route path="/" element={<h1>home</h1>} />
<Route path="/login" element={<h1>login</h1>} />
<Route path="/post/:id" element={<h1>postDetail</h1>}/>
<Route path="/edit/:id" element={<h1>postEdit</h1>} />
</Routes>
</BrowserRouter>
);
export default App;
JavaScript
복사
router 예시 (아주 간단한 예시)
•
BrowdeRouter
◦
history API를 활용해 history객체를 생성한다.
◦
history API는 내부적으로 stack 자료구조의 형태를 띄기 때문에 사용자가 방문한 url 기록들을 차곡차곡 쌓는 형태로 저장해둔다.
◦
Routing을 진행할 컴포넌트 상위에 BrowerRouter 컴포넌트를 생성하고 감싸준다,
•
Routes
◦
모든 Route의 사우이 경로에 존재해야 하며, location변경 시 하위에 있는 모든 Route를 조회해서 맞는 Route를 찾아준다.
•
Route
◦
현재 브라우저의 Location 정보를 가져온다. 상태에 따라 다른 element를 가져온다.
Route
NOTE
Route는 URL 세그먼트를 구성요소, 데이터 로딩및 데이터 변형에 연결할 수 있다!
const router = createBrowserRouter([
{
element: <Team />, // URL이 일치할 때 렌더링할 컴포넌트
path: "teams/:teamId", // 동적 경로. :teamId 부분이 URL에서 변수로 사용됩니다.
// 라우트가 렌더링되기 전에 데이터를 로드하는 함수
// 여기서는 팀 정보를 로드합니다.
loader: async ({ request, params }) => {
return fetch(`/fake/api/teams/${params.teamId}.json`, { signal: request.signal });
},
// 폼 데이터가 제출될 때 호출되는 함수
// 여기서는 팀 정보를 업데이트합니다.
action: async ({ request }) => {
return updateFakeTeam(await request.formData());
},
errorElement: <ErrorBoundary />, // 오류 발생 시 렌더링할 컴포넌트
},
]);
export default router;
JavaScript
복사
일반적인 Route작성
•
loader()를 통해 컴포넌트를 렌더링 하기전에 데이터를 가져올 수 있다.
◦
useLoadrdData() 를 사용해서 loader에서 반환한 데이터에 접근할 수 있다.
레이아웃 및 중첩된 Route
import { createBrowserRouter, RouterProvider } from "react-router-dom"
const router = createBrowserRouter([
{ path: '/',
element: <RootLayout/>,
children: [ // 자식 route 설정
{path: '/', elements: <HomePage />},
{path: '/products', element: <ProductsPage />}
},
])
// RootLayout.js
import { Outlet } from 'react-router-dom'
// ..
return(
<>
<MainNav/>
<Outlet/>
</>
)
}
JavaScript
복사
중첩 라우트
•
children 프로퍼티를 통해 중첩 라우팅을 할 수 있으며, Outlet을 이용해서 자녀 라우트 요소들을 렌더링할 장소를 표시한다.
Link
NOTE
Link 컴포넌트는 라우터 내에서 직접적으로 페이지 이동을 하고자 할 때 사용한다!
import React from 'react';
import { Link } from 'react-router-dom';
const Home = () => ( // Link로 Router 경로이동 가능
// nav는 생략해도 되지만, 접근성(SEO)에 유리하기에 작성
<div>
<h1>Home Page</h1>
<nav>
<ul>
<li>
<Link to="/signUp">signUp Page</Link>
</li>
<li>
<Link to="/signIn">signIn Page</Link>
</li>
<li>
<Link to="/post/1">Post Detail Page</Link>
</li>
<li>
<Link to="/edit/1">Post Edit Page</Link>
</li>
</ul>
</nav>
</div>
);
JavaScript
복사
•
Link는 계층 구조에 상대 경로 표현이 가능하다. (./ , ../)
•
새로고침되지 않고 페이지의 경로가 변경된다.
•
페이지 중간에 있는 컨텐츠 내부에서 tab목록을 누르는것과 같은 시도를 할 때, 기존의 Link컴포넌트였다면 클릭 시 스크롤이 초기화되어 가장 위로 이동한다.
•
useLocation Hook과 연계하여 특정 state를 넘겨주는것이 가능하다.
NavLink
NOTE
NavLink는 Link와 유사하지만 현재 경로와 일치하는 링크에 특정 스타일 및 클래스를 자동으로 적용하는 기능이 있다!
import React from 'react';
import { NavLink } from 'react-router-dom';
const Navigation = () => (
<nav>
<ul>
<li>
<NavLink to="/" className={({ isActive }) => (isActive ? 'active' : '')}>
Home
</NavLink>
</li>
<li>
<NavLink to="/about" className={({ isActive }) => (isActive ? 'active' : '')}>
About
</NavLink>
</li>
<li>
<NavLink to="/contact" className={({ isActive }) => (isActive ? 'active' : '')}>
Contact
</NavLink>
</li>
</ul>
</nav>
);
export default Navigation;
JavaScript
복사
클래스 적용
•
className: 조건에 따라 클래스를 적용할 수 있다.
Navigate
NOTE
Navigate는 컴포넌트 렌더링 로직 내에서 조건부로 페이지를 리다이렉션할 때 사용한다!
import React from 'react';
import { Navigate } from 'react-router-dom';
function ProtectedRoute({ children }) {
const isLoggedIn = // 로그인 상태를 결정하는 로직 (예: 로컬 스토리지, 상태 관리 라이브러리)
if (!isLoggedIn) {
// 사용자가 로그인하지 않았으면 로그인 페이지로 리디렉션
return <Navigate to="/login" />;
}
// 로그인한 경우에는 children 컴포넌트를 렌더링
return children;
}
export default ProtectedRoute;
JavaScript
복사
// replace: true로 주면, 현재 페이지를 히스토리스택에서 제거한다 (뒤로가기 해도 안먹힘)
// state: redirect시 설정을 넘겨준다.
<Navigate to="/dashboard" replace state={{ from: 'login' }} />
JavaScript
복사
useNavigate
NOTE
useNavigate는 프로그래밍 방식으로 라우팅을 제어하는데 사용할 수 있다!
const navigate = useNavigate();
const handleSubmit = () => {
navigate('/dashboard'); // 페이지 이동
navigate(-1); // 한 페이지 뒤로 이동
navigate('/dashboard', { replace: true }); // 현재 페이지 히스토리 제거
};
JavaScript
복사
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
function LoginForm() {
const [user, setUser] = useState(null);
const [error, setError] = useState(null);
const navigate = useNavigate(); // useNaviate 생성
useEffect(() => {
if (user) {
navigate('/dashboard', { replace: true }); // user가 존재하면 위치변경
}
}, [user, navigate]);
const handleSubmit = async (event) => {
event.preventDefault();
try {
let user = await login(event.target);
setUser(user);
} catch (error) {
setError(error);
}
};
return (
<div>
{error && <p>{error.message}</p>}
<form onSubmit={handleSubmit}>
<input type="text" name="username" />
<input type="password" name="password" />
</form>
</div>
);
}
export default LoginForm;
JavaScript
복사