요즘 코드스테이츠 immersive course에서 열심히 리액트를 배웠다. 그와 함께 배운 react-router-dom을 연습하고자 연습 페이지를 만들었다. 공식 문서를 참고하면서 연습하였으며, 아래 각 컴포넌트에 대한 설명들은 모두 공식 문서를 기반으로 작성한 것이다. (공식 문서: 링크)
시작!
아주 새로운 빈 폴더로부터 시작할 것이기 때문에 새로운 디렉토리를 만들고 create-react-app으로 리액트 프로젝트를 시작한다.
npx create-react-app .
react-rounter-dom도 받아준다. package json에도 추가해준다.
npm install react-router-dom --save
사용할 아이들을 import 해주어야 한다.
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
<BrowserRouter> (<Router>로 사용)
HTML 히스토리 API를 사용하여 URL과 UI를 맞춰주는 역할을 한다. 주로, low-level 인터페이스로 <Router>를 사용한다.
<Route>
공식 문서에 따르면, <Route>는 리액트 라우터에서 가장 중요한 컴포넌트이다. <Route>의 기본 기능은 주어진 path에 맞는 UI를 렌더링해서 보여주는 것이다.
<Switch>
자식으로 <Route> 또는 <Redirect>를 갖는데, 자식들이 지정하는 path와 일치하는 UI를 랜더링 해준다.
<Link>
앱 내에서 네비게이션을 가능하게 해준다. 아래 예시를 보면 상세하게 알 수 있다.
코드 작성
1. 상단 네비게이션 만들기
우선 맨 처음으로, <Router> 안에 네비게이션 역할을 할 div를 만들었다. 그리고 그 안에 to 속성을 가진 <Link>들을 넣어주었다.
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import './App.css';
export default function App() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/coral">Coral</Link>
</li>
<li>
<Link to="/blush">Blush</Link>
</li>
<li>
<Link to="/butterscotch">Botterscotch</Link>
</li>
<li>
<Link to="/smoke">Smoke</Link>
</li>
<li>
<Link to="/duckegg">Duck Egg</Link>
</li>
<li>
<Link to="/emeraldsea">Emeral Sea</Link>
</li>
</ul>
</nav>
</div>
</Router>
);
}
결과물은 이렇게 나온다:
각각 컬러 이름을 누르면, 주소창의 주소가 변경되는 것을 볼 수 있다.
예시) Coral을 눌렀을 때, 주소는 /coral 로 변경된다. 이게 바로 to=" " 속성이 적용된 <Link> 컴포넌트가 해주는 역할이다.
++ 그런데... 너무나 날것 그대로라서 눈이 아파왔다. 그래서 App.css를 수정해줬다. CSS는 본문 맨 마지막에 한번에 추가했다.
2. <Switch>를 부모로 <Route> 자식들을 넣어주기
그 다음으로 해야할 작업은 <Switch>를 이용해서, 변경되는 주소에 따라 매칭되는 자식 <Route>를 랜더링하도록 하는 것이다.
아래 코드는 <Switch>의 자식으로 총 6개의 <Route>가 있고, 각자의 path가 다르게 설정되어있는 가장 간단한 라우팅 구조이다. 위에서 만든 네비게이션의 <Link>를 클릭하면 url 주소가 "/선택한컬러"로 바뀌게 되는데, 이에 따라 <Switch>는 본인(?)의 자식들 중 현재 url과 동일한 path를 가지고 있는 <Route>를 선택하여 랜더링해서 보여준다.
또 한가지 주의할 점은, Home으로 지정된 기본 페이지를 보여줄 때이다. 이때의 <Route>는 자세히 보면 그냥 path="/"가 아니라 exact path="/"로 되어있다. 만약 exact를 뺄 경우엔 Home 외에 다른 어떤 옵션을 눌러도 <Switch>에 의해 Home이 채택되어 보여지게 된다. 이건 Switch가 "현재 url에 매치하는 첫번째 자식 라우트"를 선택해서 랜더링하기 때문이다. Home을 제외한 다른 옵션들도 모두 "/"로 시작하기 때문에, 현재 <Switch>의 자식들 중 가장 첫번째로 path="/"인 Home이 나왔을 때 이 첫째를 무조건 선택하는 것이다. 만약 Home을 맨 뒤로 보내서 막내를 만들어 버린다면 (아니 이런 괴상한 족보가) exact를 쓰지 않아도 무조건 home만 나오진 않게 된다.
export default function App() {
return (
<Router>
<div className="navbar">
<nav>
<ul className="navUl">
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/coral">Coral</Link>
</li>
<li>
<Link to="/blush">Blush</Link>
</li>
<li>
<Link to="/butterscotch">Botter Scotch</Link>
</li>
<li>
<Link to="/smoke">Smoke</Link>
</li>
<li>
<Link to="/duckegg">Duck Egg</Link>
</li>
<li>
<Link to="/emeraldsea">Emerald Sea</Link>
</li>
</ul>
</nav>
</div>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/coral">
<Coral />
</Route>
<Route path="/blush">
<Blush />
</Route>
<Route path="/butterscotch">
<ButterScotch />
</Route>
<Route path="/smoke">
<Smoke />
</Route>
<Route path="/duckegg">
<DuckEgg />
</Route>
<Route path="/emeraldsea">
<EmeraldSea />
</Route>
</Switch>
</Router>
);
}
아직 위에 사용된 색깔별 컴포넌트들은 만들지 않았다. 해당 컴포넌트들은 App 밖에 밑에 다가 살포시 적어준다.
function Home () {
return (
<div className="pages" style={{backgroundColor: "#F4DBA0"}}>
<h1>Collection of Spring Colors</h1>
</div>
)
}
function Coral() {
return (
<div className="pages" style={{backgroundColor: "#F4B09C"}}>
<h1>Coral</h1>
</div>
)
}
function Blush() {
return (
<div className="pages" style={{backgroundColor: "#EBC8BB"}}>
<h1>Blush</h1>
</div>
)
}
function ButterScotch() {
return (
<div className="pages" style={{backgroundColor: "#E7B563"}}>
<h1>Butter Scotch</h1>
</div>
)
}
function Smoke () {
return (
<div className="pages" style={{backgroundColor: "#A3B0B4"}}>
<h1>Smoke</h1>
</div>
)
}
function DuckEgg() {
return (
<div className="pages" style={{backgroundColor: "#BCCFC8"}}>
<h1>Duck Egg</h1>
</div>
)
}
function EmeraldSea() {
return (
<div className="pages" style={{backgroundColor: "#5B8F8E"}}>
<h1>Emerald Sea</h1>
</div>
)
그리고서 실행시키면 결과물은 아래와 같다:
요약
이와 같이 아주 간단하게 React Router를 사용할 수 있다:
- <Link>로 네비게이션의 페이지들을 링크해준다. url의 뒤 path가 이로 인해 변경된다.
- 변경된 path에 따라 보여줄 컴포넌트들을 <Switch>의 자식 <Route>로 만들어준다.
App.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#root {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.navUl {
padding: 1rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 5px 5px 30px 5px rgba(0,0,0,0.2);
list-style: none;
}
.navUl a {
text-decoration: none;
color: black;
}
.pages {
flex: 1 1 auto;
display: grid;
place-content: center;
color: #fff;
}
'Learn to Code' 카테고리의 다른 글
[React] React hooks 연습: 간단한 To-Do 리스트 (0) | 2021.05.18 |
---|---|
Redux 기본 개념 정리 (4) | 2021.05.16 |
[JS] React에서 배열인 state에 아이템을 추가하고 싶다면!? (concat()과 Spread Syntax) (0) | 2021.05.07 |
[TIL] node.js 미니 서버 만들기 (0) | 2021.04.30 |
[TIL] 코드스테이츠 chatterbox (client) 과제 (ongoing) (0) | 2021.04.29 |
댓글