: 클라이언트 측 라우팅 지원
// index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// App.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import {
createBrowserRouter,
RouterProvider,
} from "react-router-dom";
const router= createBrowserRouter([
{
path: '/',
element: <Root />,
errorElement: <ErrorPage />,
children: [
{path:'/', element:<Main />},
{path:'/profile', element:<Profile />},
]
}
]);
function App() {
return (
<>
<RouterProvider router={router} />
</>
);
}
export default App;
: Route 구성을 감싸기 위한 부모 요소
→ react-router v6에서는 <Switch>
를 <Routes>
로 변경
v5에서 사용되었을 때
<Router>
<Switch>
<Route exact path="/">
<Main />
<Route>
<Route path="/profile">
<Profile />
</Route>
</Switch>
</Router>
v6에서 사용되었을 때
<Routes>
<Route exact path="/">
<Main />
<Route>
<Route path="/profile">
<Profile />
</Route>
</Routes>
<Link>
는 사용자가 클릭 하거나 탭 하여 다른 페이지로 이동할 수 있게 해주는 요소
import React from 'react';
import { Link } from 'react-router-dom';
function Main(){
return(
<Link to='/profile'>
프로필
</Link>
);
}
react-router-dom v6부터는 history, useHistory → useNavigate
교체
import React from 'react';
import {useNavigate} from 'react-router-dom';
function Main(){
const navigate = useNavigate();
// 뒤로 가기
const handleGoBack = () =>{
navigate(-1);
}
//홈으로 가기
const handleGoHome = () =>{
navigate('/');
}
return(
<>
<button onClick={handleGoBack}>뒤로가기</button>
<button onClick={handleGoHome}>홈가기</button>
</>
)
}
라우터의 경로에 유동적인 값 넣어서 특정 경로로 이동
→ URL 파라미터와 쿼리스트링으로 나눠짐
주소의 경로에 유동적인 값을 넣는 형태 → /class/3
<Route path=”/class/:id” element={<Class />} />
const {id} = useParams();
→ id는 파라미터에서 설정한 :뒤의 값// App.js
<Router>
<Routes>
<Route element={<Header />}>
<Route path="/" element={<Home />} />
</Route>
<Route path="/class" element={<Student />}>
<Route path=":id" element={<Class />}>
<Route path=":snum" element={<StudentDetail />} />
</Route>
</Route>
</Routes>
</Router>
// Student.js -> 반 목록 조회
import React from "react";
import { Link, Outlet } from "react-router-dom";
function Student() {
return (
<>
<ul>
<li>
<Link to="/class/1">1반</Link>
</li>
<li>
<Link to="/class/2">2반</Link>
</li>
<li>
<Link to="/class/3">3반 </Link>
</li>
</ul>
<hr />
<Outlet />
</>
);
}
export default Student;
// Class.js -> 해당 반 정보와 학생 리스트
import React from "react";
import { useParams, Link, Outlet } from "react-router-dom";
function Class() {
const { id } = useParams();
console.log(id);
return (
<>
<h1>이곳은 {id} 반 입니다.</h1>
<h2>학생 정보</h2>
<ul>
<li>
<Link to={`/class/${id}/1`}>kim</Link>
</li>
<li>
<Link to={`/class/${id}/2`}>lee</Link>
</li>
<li>
<Link to={`/class/${id}/3`}>park</Link>
</li>
</ul>
<hr />
<Outlet />
</>
);
}
export default Class;
// StudentDetail.js -> 해당 학생 상세정보
import React from "react";
import { useParams, useNavigate } from "react-router-dom";
const studentData = {
1: {
name: "kim",
sNum: 1,
major: "computer",
},
2: {
name: "lee",
sNum: 2,
major: "design",
},
3: {
name: "park",
sNum: 3,
major: "nano",
},
};
function StudentDetail() {
const navigate = useNavigate();
const { snum } = useParams();
console.log(snum);
const student = studentData[snum];
return (
<div>
{student ? (
<div>
<h3>이름: {student.name}</h3>
<div>학번: {student.sNum}</div>
<div>전공: {student.major}</div>
</div>
) : (
<>
<div>존재하지 않는 학생입니다.</div>
<button onClick={() => navigate(-1)}>뒤로가기</button>
</>
)}
</div>
);
}
export default StudentDetail;
: 주소의 뒷부분에 ? 문자열 이후에 key=value로 값을 정의하며, &로 구분하는 형태
→ 키워드 검색, 페이지네이션, 정렬 방식 등 데이터 조회에 필요한 옵션 전달 시 사용
ex) /articles?page=1&keyword=react
useLocation()
→ location
객체 반환(현재 사용자가 보고 있는 페이지 정보)useSearchParams
훅 이용하면 편함 const [searchParams, setSearchParams]=useSearchParams();
get
: 특정 쿼리파라미터 조회 const detail=serachParams.get(’detail’);
set
: 특정 쿼리파라미터 업데이트 가능 setSearchParams({mode,detail:detail===’true’?false:true});
ex)
import React from "react";
import { useSearchParams } from "react-router-dom";
function About() {
const [searchParams, setSearchParams] = useSearchParams();
const user = searchParams.get("user");
const keyword = searchParams.get("keyword");
const page = searchParams.get("page");
const changeIsUser = () => {
setSearchParams({
user: user === "true" ? false : true,
keyword,
page,
});
};
const countPage = () => {
const plusPage = page === null ? 1 : parseInt(page) + 1;
setSearchParams({ user, keyword, page: plusPage });
};
return (
<div>
<h1>소개</h1>
<p>쿼리스트링 react-router-dom v6</p>
<p>유저인가요? {user}</p>
<p>검색한 키워드: {keyword}</p>
<p>페이지번호: {page}</p>
<button onClick={changeIsUser} style={{ marginRight: "3rem" }}>
유저여부 변경
</button>
<button onClick={countPage}>페이지번호증가</button>
</div>
);
}
export default About;
유저여부 변경 버튼 클릭
페이지 번호증가 버튼 두번 클릭
→ Outlet 컴포넌트 사용: Route의 childeren으로 들어가는 JSX 엘리먼트 보여주는 역할
ex)
1. 홈화면에 헤더 보이고 싶을 경우
// App.js
// 자식 컴포넌트 Route를 안에 감싼다.
function App() {
return (
<Router>
<Routes>
<Route element={<Header />}>
<Route path="/" element={<Home />} />
</Route>
<Route path="/class" element={<Student />}>
<Route path=":id" element={<Class />} />
</Route>
</Routes>
</Router>
);
}
// Home.js
import React from "react";
import { Link } from "react-router-dom";
function Home() {
return (
<div>
<h1>홈입니다.</h1>
<Link to="/class">교실가기</Link>
</div>
);
}
export default Home;
// Header.js
import React from "react";
import { Outlet } from "react-router-dom";
// Outlet컴포넌트 사용하여 자식 컴포넌트 나오게끔
function Header() {
return (
<>
<h1 style={{ background: "lime", width: "100%", height: "4rem" }}>
헤더
</h1>
<Outlet />
</>
);
}
export default Header;
// Student.js -> 전체 반 정보 출력
import React from "react";
import { Link, Outlet } from "react-router-dom";
function Student() {
return (
<>
<ul>
<li>
<Link to="/class/1">1반</Link>
</li>
<li>
<Link to="/class/2">2반</Link>
</li>
<li>
<Link to="/class/3">3반 </Link>
</li>
</ul>
<hr />
<Outlet />
</>
);
}
export default Student;