React Router v6 기준으로 작성됨.
Single Page Application: 말 그대로 한 개의 페이지로 이루어져 있는 애플리케이션을 말한다.
Routing이라 한다.code spliting을 이용하면 라우트별로 파일들을 나누어서 트래픽과 로딩속도를 개선할 수 있다.HTML5 History API를 사용하여 페이지를 새로고침하지 않고 주소를 변경한다.// index.js
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>
a 태그로 이루어져 있지만, 페이지 전환을 방지하는 기능이 내장되어 있다.HTML5 History API를 이용하여 페이지의 주소만 변경한다.<Link to="주소">내용</Link>
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>
페이지 주소를 정의할 때 가끔은 유동적인 값을 전달해야 할 때가 있다.
/profile/eunnbi)/about?details=true)useParams()를 이용하여 URL 파라미터를 객체 형태로 조회할 수 있다.<Route path="/profiles/:username" element={<Profile/>}/>
const Profile = () => {
const { username } = useParams();
...
}
location 객체의 search 프로퍼티에서 조회할 수 있다.location 객체는 useLocation()를 이용하여 조회할 수 있다.useSearchParams()를 이용하여 쿼리 스트링을 쉽게 다룰 수 있다.get메서드를 통해 특정 쿼리파라미터를 조회할 수 있고, set메서드를 통해 특정쿼리 파라미터를 업데이트할수 있다.const About = () => {
const [ searchParams, setSearchParams] = useSearchParams();
const detail = searchParams.get("detail");
const onToggleDetail = () => {
setSearchParams({ detail: detail === "true" ? false : true});
}
return (
<div>
<h1>About</h1>
<p>This page is About</p>
<button onClick={onToggleDetail}>Toggle detail</button>
{detail && <p>details</p>}
</div>
);
}
라우트 내부에 또 라우트를 정의하는 것
// App.js
...
return(
<Link to="/profiles">PROFILE</Link>
<Routes>
<Route path="/profiles/*" element={<Profiles/>}/>
</Routes>
);
// Profiles.js
...
return(
<Link to="eunnbi">eunnbi</Link>
<Routes>
<Route path=":username" element={<Profile/>}/>
</Routes>
);
Profiles 컴포넌트 내부에서 또 다시 Route를 정의했다.Profiles 컴포넌트 밑으로 파라미터에 따라 다른 Profile 컴포넌트가 보여진다.// App.js
...
return(
<Link to="/profiles">PROFILE</Link>
<Routes>
<Route path="/profiles" element={<Profiles/>}>
<Route path=":username" element={<Profile/>}/>
</Route>
</Routes>
);
// Profiles.js
...
return(
<Link to="eunnbi">eunnbi</Link>
<Outlet/>
);
Profiles 컴포넌트에 있던 Route 컴포넌트를 옮겨 라우트를 중첩시켰다.Profiles 컴포넌트에는 Outlet 컴포넌트가 사용되었다.
Outlet컴포넌트는 자식 라우트에서 보여지는 컴포넌트를 부모 라우트 컴포넌트에서 렌더링하기 위해 사용되어야 한다.
Oulet은 페이지끼리 공통적으로 보여줘야 하는 컴포넌트가 있을 때 유용하게 사용된다.const Layout = () => {
return (
<div>
<header>
...
</header>
<main>
<Outlet/>
</main>
</div>
);
}
const App = () => {
return(
<Routes>
<Route element={<Header/>}>
<Route path="/" element={<Home/>}/>
<Route path="/about" element={<About/>}/>
</Route>
</Routes>
);
}
useNavigate()는 Link 컴포넌트를 이용하지 않고도 다른 화면으로 이동해야 하는 상황에 사용한다.const navigate = useNavigate();
navigate 함수는 두 가지 방법으로 사용 가능하다.to)를 전달하고 두 번째 인자로는 replace 혹은 state를 전달한다. Link의 to props와 동일한 형태로 넣으면 된다.navigate(to, { replace: true }): 페이지를 이동할 때 현재 페이지를 페이지 기록에 남기지 않는다.navigate(to, { state })navigate(-1): 뒤로 가기Navigate 컴포넌트를 사용한다.참고