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
컴포넌트를 사용한다.참고