리액트에서 SPA(Single Page Application)을 제작 하기 위해서는 Router(라우터)
라는 라이브러리가 필요하다.
한 개의 페이지에서 라우터를 이용해서 여러 개의 페이지를 만들 수 있는 것이다.
터미널로 npm을 통해서 라우터를 설치한다.
npm install react-router-dom
import
로 'react-router-dom'
에서 { BrowserRouter, Routes, Route }
를 불러온다.BrowserRouter > Routes > Route
의 구조로 이루어 진다.Route
에는 path
와 element
속성으로 이루어져 있는데, path
는 페이지 URL의 맨 뒤 경로를 나타내고 element
에는 path의 경로에 진입했을 때 보여줄 컴포넌트
가 와야한다.
- Home의 기본 주소 : 진입 시
<Home />
컴포넌트를 불러온다.
- path='/detail' 인 주소 : 진입 시
<Detail />
컴포넌트를 불러온다.
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './routes/Home';
import About from './routes/About';
import Navigation from './components/Navigation';
function App() {
return (
<BrowserRouter>
<Navigation />
// Routes : Route의 모음
<Routes>
// Route : 클릭을 했을 때 해당되는 주소의 컴포넌트를 불러오는 역할
<Route path='/' element={<Home />} />
<Route path='/about' element={<About />} />
<Route path='/detail' element={<Detail />} />
</Routes>
</BrowserRouter>
);
}
export default App;
라우터는 라우터를 통해서 이동하는 페이지와 일반페이지를 구분한다. 주로 src
폴더에 components
폴더와 routes
폴더로 구분한다.
HTML5 History API
를 사용하여 페이지를 새로고침하지 않고 주소를 변경한다.import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
// 필수
<BrowserRouter>
<App/>
</BrowserRouter>
);
path props
)에 따라 어떤 컴포넌트(element props
)를 보여줄지 정의한다.<Route path="주소규칙" element={<컴포넌트 이름/>}/>
Route
컴포넌트들은 반드시 Routes
의 자식 컴포넌트여야 한다.Routes
는 여러 Route
를 감싸서 주소규칙이 가장 일치하는 하나의 라우트를 렌더링한다.Not Found
화면도 구현할 수 있다.path props
을 "/*"
라고 설정하면 해당 Route는 모든 경로에 매치가 가능
하다.나머지 Route
의 주소규칙과 일치하지 않았다면 이 Route가 렌더링된다.<Routes>
<Route path="/" .... />
<Route path="/*" element={<NotFound/>}/>
</Routes>
App.js
에서 라우터로 지정해놓은 경로들을 사용해서 해당 컴포넌트를 불러온 페이지로 이동시켜 주는 컴포넌트다.a 태그
로 이루어져 있지만, 페이지 전환을 방지하는 기능이 내장되어 있다.HTML5 History API
를 이용하여 페이지의 주소만 변경한다.import { Link } from 'react-router-dom';
로 Link를 불러오고 사용해야 한다.<Link to="주소">내용</Link>
Link를 사용하지만 실제 브라우저에서는 a태그로 표기되어서 CSS 스타일 적용도 a태그로 적용한다.
Link 컴포넌트
와 유사하지만 현재 사용자 브라우저 경로와 to props
의 경로가 일치하는 경우 특정 스타일
혹은 CSS 클래스
를 적용할 수 있는 컴포넌트이다.const activeStyle={
textDecoration: "underline"
};
const activeClassName = "underline";
<NavLink to="messages" style={({ isActive }) => isActive ? activeStyle : undefined}>Messages</NavLink>
<NavLink to="messages" className={({ isActive }) => isActive ? activeClassName : undefined}>Tasks</NavLink>
리액트의 클래스형 컴포넌트
는 props를 통해서 하위 컴포넌트에게 단방향 데이터를 전송 할 수 있다. 하지만 하위가 아닌 하위의 하위(자손)컴포넌트로는 한 번에 데이터를 보낼 수 없다. 반드시 상위 컴포넌트를 통해서 데이터를 받을 수 있는 것 이다.
이 문제는 함수형 컴포넌트의 useState
나 Redux
라이브러리를 통해 직접 데이터를 보낼 수 있는 해결법이 있다.
하지만 오늘은 라우터의 useLocation
으로 다른 컴포넌트에게 데이터를 전달 할 수 있는 법을 배웠다.
상위 컴포넌트에서 props
나 구조분해할당
을 통해 하위 컴포넌트가 받은 데이터를 라우터를 통해 다른 컴포넌트로 데이터를 전송하는 법이다.
Link태그의 to프로퍼티로 URL의 주소를 지정하고 state프로퍼티로 보낼 데이터(props / 구조분해할당)를 지정해주면 된다.
이 때, 데이터는 브라우저의 URL을 통해서 보내진다.
/* 상위로부터 props로 받고 하위에게 props로 보내는 법 */
import React from 'react';
import { Link } from 'react-router-dom';
export default function Component(props) {
const {data1, data2, data3...} = props;
return (
<Link to={'/detail'} state={props}>
);
}
/* 상위로부터 구조분해할당으로 받고 하위에게 구조분해할당으로 보내는 법 */
import React from 'react';
import { Link } from 'react-router-dom';
export default function Component({data1, data2, data3...}) {
return (
<Link to={'/detail'} state={{data1, data2, data3...}}>
);
}
다른 컴포넌트의 데이터(props)
를 useLocation
을 통해 받아와 변수에 할당한다.
import React from 'react';
import { useLocation } from 'react-router-dom';
export default function Detail() {
const location = useLocation();
console.log(location); // 객체 형태로 데이터가 콘솔에 찍힘
}
객체형태로 받아진 데이터의 키값
을 구조분해할당 하여 사용한다.
const { title, year, summary, poster, genres } = location.state;