[React] 페이지 라우팅
- Routing: 어떤 네트워크 내에서 통신 데이터를 보낼 경로를 선택하는 일련의 과정
- Page Routing: 요청에 따라서 서버에서 어떤 페이지를 보내줄 것인지를 선택하는 과정
- MPA: Multipage Application -> 페이지가 이동할 때마다 서버에 요청 -> 페이지 선택, 페이지 이동을 완료시킴
- SPA: Single Application -> 페이지가 한 개밖에 없으므로 한 개의 페이지만 제공
- CSR: Client Side Rendering -> 리액트가 MPA 처럼 작동할 수 있는 원리
React Router library 사용
https://reactrouter.com/ 여기에서 installation 카테고리로 들어가서 npm install react-router-dom@6
을 터미널에 입력
src > pages 폴더 생성
pages 폴더 안에는 각 페이지에 해당하는 .js 파일을 만들어 준다.
EMOTION-DIARY에서는 Home, New, Edit, Diary 4개의 .js 파일을 만들었다.
각 폴더 안에 해당 코드를 기능에 맞게 넣는다.
const Home = () => {
return (
<div>
<h2>Home</h2>
<p>이곳은 Home입니다. </p>
</div>
);
};
export default Home;
페이지 라우팅하기
// src > App.js
import "./App.css";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import New from "./pages/New";
import Edit from "./pages/Edit";
import Diary from "./pages/Diary";
function App() {
return (
<BrowserRouter>
<div className="App">
<h2>App.js</h2>
<Routes>
<Route path="/" element={<Home></Home>}></Route>
<Route path="/new" element={<New></New>}></Route>
<Route path="/edit" element={<Edit></Edit>}></Route>
<Route path="/diary" element={<Diary></Diary>}></Route>
</Routes>
</div>
</BrowserRouter>
);
}
export default App;
이렇게 된다면 Routes 태그 안에 있는 Route 태그들만 path에 따라서 변하게 된다. 따라서 뭔가 공통적으로 모든 페이지에 넣고 싶은 부분이 있다면 Routes 태그 밖으로 빼면 된다.
SPA 방식으로 페이지 연결하기
RouteTest 컴포넌트를 하나 임시로 만들어서 어떻게 페이지상에서 컴포넌트들끼리 연결이 되는지를 확인해본다.
// src > components > RouteTest.js
import { Link } from "react-router-dom";
const RouteTest = () => {
return (
<div>
<h2>RouteTest</h2>
<p>CSR 방식으로 페이지를 이동하기 위한 test 컴포</p>
<Link to={"/"}>Home</Link>
<br />
<Link to={"/diary"}>Diary</Link>
<br />
<Link to={"/edit"}>Edit</Link>
<br />
<Link to={"/new"}>New</Link>
</div>
);
};
export default RouteTest;
페이지들은 Link 태그를 통해서 이동한다. html의 a 태그와 유사하지만 a 태그의 경우는 MPA 방식이기 때문에 이렇게 설정함…
React Router Dom의 유용한 기능
React Router V6
- Path Variable
- QueryString
- Page Moving
Path Variable
diary 컴포넌트는 무조건 path=”/diary/:id” 형식으로 전달할 것이기 때문에 App 컴포넌트에 diary Path를 다음과 같이 수정한다.
// src > App.js
<Route path="/diary/:id" element={<Diary></Diary>}></Route>
그럼 diary 컴포에 id를 불러올 수 있어야 한다.
useParams 라는 사용자 지정 Hooks를 사용해서 리턴하는 객체들 중에서 id 값을 사용한다.
// src > pages > Diary.js
import { useParams } from "react-router-dom";
const Diary = () => {
const { id } = useParams();
console.log(id);
return (
<div>
<h2>Diary</h2>
<p>이곳은 일기 상세 페이지입니다. </p>
</div>
);
};
export default Diary;
근데 저기에 있는 id라는 값은 굳이 id가 아니어도 App 컴포랑 연결이 되어있다면 변수이름은 어떤 것이든 상관이 없을 것 같다.
Query String
웹 페이지에 데이터를 전달하는 가장 간단한 방법. 따로 App 컴포에서 라우터는 필요없고, 링크 주소에 ? 뒤에 있는 값들을 받아올 수 있다.
링크 이름을 http://localhost:3000/edit?id=19000&mode=dark
이렇게 한다면 ? 뒤에 있는 값들을 searchParams 를 통해서 가져올 수 있다.
// src > pages > Edit.js
import { useSearchParams } from "react-router-dom";
const Edit = () => {
const [searchParams, setSearchParams] = useSearchParams();
const id = searchParams.get("id");
console.log("id: ", id);
const mode = searchParams.get("mode");
console.log("mode: ", mode);
return (
<div>
<h2>Edit</h2>
<p>이곳은 일기 수정 페이지입니다. </p>
</div>
);
};
export default Edit;
useSearchParams는 useState 처럼 searchParams는 값을 저장하고 있는 변수고, searchParams가 변경된다면 setSearchParams를 통해서 변경이 된다. searchParams는 get 함수를 이용해서 가져올 수 있다.
Page Moving
useNavigate 라는 Hook을 사용해서 페이지를 이동시킬 수 있는 함수를 반환을 해주어서 navigate라는 변수에 받은 것이다. 인자로 경로를 작성해주면 경로를 옮겨줄 수 있다.
import { useSearchParams, useNavigate } from "react-router-dom";
const Edit = () => {
const navigate = useNavigate();
const [searchParams, setSearchParams] = useSearchParams();
const id = searchParams.get("id");
console.log("id: ", id);
const mode = searchParams.get("mode");
console.log("mode: ", mode);
return (
<div>
<h2>Edit</h2>
<p>이곳은 일기 수정 페이지입니다. </p>
<button onClick={() => setSearchParams({ who: "ssk" })}>QS 바꾸기</button>
<button
onClick={() => {
navigate("/home");
}}
>
HOME으로 가기
</button>
</div>
);
};
export default Edit;
댓글남기기