*Udemy의 "Complete React Developer in 2020" 강의에서 학습한 내용을 정리한 포스팅입니다.
*자바스크립트와 리액트를 배우는 단계라 오류가 있을 수 있습니다. 틀린 내용은 댓글로 말씀해주시면 수정하겠습니다. 감사합니다. :)
1. 리액트에서 라우팅하기
리액트로 구현하는 웹페이지는 대부분 Single Page Application, 즉 HTML 파일은 하나만 가지고 있고, 나머지는 자바스크립트로 화면을 통제하여 서버와의 요청/응답 주고받기를 줄여 웹페이지의 로딩 속도를 줄이는 방식을 취하고 있다. 속도 측면에서는 SPA가 장점이 뚜렷하지만, 페이지 간 이동 시 주소의 문제가 발생한다.
예를 들면, 원래는 페이지에 따라서 url link가 달라지게 된다. www.soldonii.com/shop/hats 이런식으로 이동하는 페이지마다 주소가 달라지게 된다. 그런데 SPA는 구조 상 단일 페이지이기 때문에 보여지는 페이지 모습은 달라져도 주소는 달라지지 않는 문제가 발생한다. 이러한 문제를 해결해주기 위해서 등장한 라이브러리가 React Router 라이브러리이다.
# 설치 및 사용법
terminal에서 작업 중인 리액트 프로젝트 폴더로 이동한 후, yarn add react-router-dom으로 설치한다. 이후 프로젝트에 적용하기를 원하면 index.js에서 아래처럼 import하면 된다. 그리고 ReactDOM.render에서 #root를 대체할, 베이스가 되는 App 컴포넌트를 아래처럼 <BrowserRouter>로 감싸주어야 한다. 그렇게 함으로써 react-router-dom 라이브러리가 가지고 있는 모든 기능을 App 컴포넌트가 사용할 수 있게된다.
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom'; // 이렇게 import한다.
import './index.css';
import App from './App';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
2. Route 컴포넌트 사용하기
react-router-dom 라이브러리에는 무수히 많은 컴포넌트가 존재한다. 그 중 대표적인 <Route> 컴포넌트를 알아보자.
// App.js
import React from 'react';
import { Route } from 'react-router-dom';
import HomePage from './pages/homepages/homepage.component';
import './App.css';
const HatsPage = () => (
<div>
<h1>HATS PAGE</h1>
</div>
)
function App() {
return (
<div>
<Route exact path="/" component={HomePage}/>
<Route path="/hats" component={HatsPage}/>
</div>
);
}
export default App;
위에서 리턴되는 부분을 보면 기존처럼 구현한 컴포넌트를 div에 담는 대신 <Route> 컴포넌트를 div에 담고, rendering이 필요한 컴포넌트를 <Route> 컴포넌트의 프로퍼티로 전달하고 있다.
# <Route> 컴포넌트의 주요 프로퍼티 - component, path, exact
1. component는 <Route>가 rendering해야 하는 대상이 되는 컴포넌트를 의미한다.
2. path는 rendering할 대상이 되는 컴포넌트의 주소를 의미한다. 위의 경우 localhost:3000/ 주소는 HomePage 컴포넌트가 렌더링되고, localhost:3000/hats는 HatsPage 컴포넌트가 렌더링된다.
3. exact는 값으로 true, false를 줄 수 있다. 만약 true일 경우 exact={true} 대신 축약해서 exact만 작성하면 된다.
function App() {
return (
<div>
<Route path="/" component={HomePage}/>
<Route path="/hats" component={HatsPage}/>
</div>
);
}
만약 위 코드처럼 <Route> 컴포넌트에 exact를 뺄 경우 어떻게 될까? 위 코드에서 localhost:3000/hats 로 접속하면 HomePage 컴포넌트와 HatsPage 컴포넌트가 모두 렌더링된다. 왜냐하면 exact가 없을 경우 localhost:3000/hats 라는 주소 내에 HomePage 컴포넌트가 렌더링되어야 하는 주소인 localhost:3000/ 주소가 포함되어 있기 때문이다. 따라서 localhost:3000/hats 이 주소는 HomePage와 HatsPage 컴포넌트 둘 모두 렌더링 되는 것이다.
이를 해결하기 위해서 exact 프로퍼티가 필요한 것이다.
function App() {
return (
<div>
<Route exact path="/" component={HomePage}/>
<Route path="/hats" component={HatsPage}/>
</div>
);
}
이렇게 HomePage 컴포넌트의 경우 프로퍼티로 exact를 작성해주면, 주소가 정확히 localhost:3000/ 일 때에만 HomePage 컴포넌트가 렌더링된다. localhost:3000/hats 주소는 비록 localhost:3000/을 포함하고 있지만, 정확히 localhost:3000/ 이 주소일 때에만 HomePage 컴포넌트가 렌더링되도록 했으므로 HomePage 컴포넌트는 렌더링되지 않고 오직 HatsPage 컴포넌트만 렌더링된다.
# Switch 컴포넌트
import React from 'react';
import { Route, Switch } from 'react-router-dom'; // Switch도 렌더링
import HomePage from './pages/homepages/homepage.component';
import './App.css';
const HatsPage = () => (
<div>
<h1>HATS PAGE</h1>
</div>
)
function App() {
return (
<div>
<Switch>
<Route path="/" component={HomePage}/>
<Route path="/hats" component={HatsPage}/>
</Switch>
</div>
);
}
export default App;
exact를 주지 않았을 때, 앞선 <Route> 컴포넌트에서는 localhost:3000/hats 라는 주소의 경우 path="/"도 일치하고, path="/hats"도 일치했으므로 HomePage 컴포넌트와 HatsPage 컴포넌트 모두를 렌더링했다. 그런데 이를 <Switch> 컴포넌트 내부에 종속시키면 <Switch> 컴포넌트 내부에 있는 <Route> 컴포넌트들 중 위에서부터 url과 일치하는 것 하나만을 렌더링한다.
따라서 위 코드를 기반으로 만약 localhost:3000/hats 라는 주소에 접속할 경우에, 기존에는 HomePage와 HatsPage가 모두 렌더링됐다면, Switch 안에 들어가는 순간 HomePage 컴포넌트만 렌더링된다. 위에서부터 path와 일치하는 것을 찾는데, HomePage 컴포넌트는 localhost:3000/hats 주소에서 /가 포함되어 있으므로 렌더링이 되기 때문이고, 하나가 렌더링되면 나머지는 렌더링되지 않기 때문이다.
'Javascript 공부 > React' 카테고리의 다른 글
withRouting()으로 프로퍼티 전달하기 (0) | 2019.12.16 |
---|---|
리액트 라우터(React Router)로 컴포넌트에 프로퍼티 전달하기 (1) | 2019.12.15 |
리액트의 생명 주기(LifeCycle) 메소드 (0) | 2019.12.12 |
비동기로 작동하는 setState 이해하기 (0) | 2019.12.11 |
리액트에서 state를 다룰 때 주의해야 할 점 (0) | 2019.12.10 |
댓글