전 시간에도 다뤘기 때문에 간략하게만 적고 가겠다.
다른 주소에 다른 화면을 보여준다. - 라우팅
라우팅 라이브러리는 크게 3개가 있는데 (혹시 몰라 신흥강자가 나타났을지도. 근데 일단 난 모름)
리액트 라우터
, 리치 라우터
, Next.js
가 바로 그것이다.
만약 리치 라우터의 리치가 Rich
였으면 난 주저않고 리치 라우터를 썼겠지만, 아쉽게도 Reach
다.
이 중에 가장 역사가 오래되기도 했고, 나중에 익혀볼 서버 사이드 렌더링에 적합하며 가장 많이 쓰이는 리액트 라우터를 알아보자.
yarn add react-router-dom
일단, 리액트가 공식적으로 지원하는 라우터 기능이 없기 때문에 라이브러리를 설치해야 한다.
당연히 이걸 설치하기 전에 리액트 프로젝트부터 CRA
를 통해 만들어두자.
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
그 후 src/index.js
파일에서 저 부분을 다음과 같이 바꿔보자.
import { BrowserRouter } from 'react-router-dom';
(... 중략)
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
이 BrowserRouter
란 뭘까? HTML5
의 History API
를 사용하여 페이지를 새로고침하지 않고도 주소를 변경할 수 있도록 해준다.(즉, 페이지 변경으로 인한 깜빡거림이 없다.)
또, 현재 주소에 관련된 정보를 props
로 조회 및 사용이 가능하도록 만들어준다.
// Home.js
import React from 'react';
/**
* 함수형 컴포넌트 스니펫입니다.
*/
const Home = () => {
return (
<div>
<h1>Home</h1>
<p>Take me home~ Country road~</p>
</div>
);
};
export default Home;
src
디렉토리에 Home.js
파일을 만들어보자. 또, About.js
도 만들어보자.
// About.js
import React from 'react';
/**
* 함수형 컴포넌트 스니펫입니다.
*/
const About = () => {
return (
<div>
<h1>열정적으로 살고 싶다.</h1>
<p>리액트 라우터 한 방에 끝내버리자.</p>
</div>
);
};
export default About;
당연한 얘기지만 안의 내용물은 마음대로 적어도 된다. 저거 바꾼다고 결과에 아무런 지장이 없다.
import React from 'react';
import About from './About';
import Home from './Home';
function App() {
return (
<div>
<Home />
<About />
</div>
);
}
export default App;
홈을 이렇게 만들고, yarn start
를 통해서 리액트 렌더링을 해보자.
결과값은 다음과 같고 하나하나 설명해보겠다.
index.js
에서 ReactDOM.render(<App />)
를 썼기 때문에 localhost:3000
에는 App.js
컴포넌트가 렌더링이 된다.하지만 우리가 원하는 것은 이게 아니다. localhost:3000
에선 Home 컴포넌트가, localhost:3000/about
에선 About 컴포넌트가 렌더링되었으면 좋겠다.
import React from 'react';
import About from './About';
import Home from './Home';
import { Route } from 'react-router-dom';
function App() {
return (
<div>
<Route path="/" component={Home} />
<Route path="/about" component={About} />
</div>
);
}
export default App;
App.js
를 위와같이 바꿔보자. Route
라는 못 보던 컴포넌트가 보이는데, 이게 바로 주소에 따라 다른 화면을 보여주는 라우팅 기능을 가진 컴포넌트이다. path=""
부분에는 바뀔 주소의 이름을 적고, component={}
부분에는 렌더링될 컴포넌트를 집어넣는다.
<Route path="/이동할 주소" component={출력할 컴포넌트}/>
나같은 경우는 위에 내가 원했던 것처럼 메인에선 Home.js
가 뜨길 바랐고, /about
에선 About.js
에서 뜨길 바랐으니 위와같이 코드를 적었다.
결과값은 다음과 같다.
보다시피 About 컴포넌트가 지워진 것을 알 수 있다. 메인화면에선 Home 컴포넌트만 렌더링 되도록 설정해놨기 때문이다.
다음은 /about
으로 이동해 페이지 렌더링이 완료된 모습인데, 뭔가 이상하다.
분명 나는 Home 컴포넌트를 이 주소에 넣어준 기억이 없는데 이 놈은 왜 출력된걸까?
왜냐하면 /about
에 /
가 들어있기 때문이다. 그래서 둘 다 포함이 되니까 출력된 것
이 것은 exact
라는 옵션으로 해결이 가능하다.
<Route path="/이동할 주소" component={출력할 컴포넌트} exact/>
아, 여기서 주의할 점은 About
쪽 Route를 바꾸는게 아니라, Home
쪽을 바꿔줘야 한다.
exact
의 의미는 정확히 이 path
에서만 해당 라우팅을 이뤄지도록 하라는 명령인데, 원래는 exact={true}
가 맞지만, true
는 생략해도 된다는 건 리액트의 기초.
<div>
<Route path="/" component={Home} exact />
<Route path="/about" component={About} />
</div>
다음과 같이 App.js
를 수정해주고 결과를 다시 확인해보자
아주 잘 나온다.
<a href="localhost:3000/about">
와 같은 태그를 사용할 경우에도 위와 동일한 결과가 나오겠네?
아니, 사용하면 안 된다. Route
를 사용하는 이유는 현재 페이지에서 상태를 유지하면서 바뀐 주소에 따라 바뀐 화면만 보이고 싶을 뿐인데, a
태그를 사용할 경우, 상태가 전부 날라가버린다. 또 기존의 렌더링된 컴포넌트를 다 날려버리고 처음부터 렌더링이 진행된다.
위에서 썼던 이 부분을 기억하자.
HTML5
의History API
를 사용하여 페이지를 새로고침하지 않고도 주소를 변경할 수 있도록 해준다.(즉, 페이지 변경으로 인한 깜빡거림이 없다.)
이 부분은 <a>
로는 구현이 안 된다. BrowserRouter
를 이용한 다른 무언가를 사용해야 한다. 그게 바로 Link다.
Link
컴포넌트는 클릭하면 다른 주소로 이동하는 과정에서 페이지를 새로 불러오지 않고 유지한 상태에서 History API
만을 사용하여 페이지의 주소만 변경해준다. Link
컴포넌트는 한마디로 a
의 상속버전이라고 봐도 무방한데, 컴포넌트 자체로는 a
로 이뤄져 있지만, 추가적으로 페이지 전환을 방지하는 기능이 들어있다.
<Link to='이동할주소'>내용</Link>
사용법은 위와 같다.
Route
를 사용했을때는, 우리가 직접 URL
을 주소창에 입력해야지만 다른 페이지로 넘어갈 수 있었다. 하지만 어떤 X신같은 웹사이트도 그런식으로 주소 이동을 하진 않는다. 로그인을 하려고 로그인 버튼을 누르는게 아니라 http://localhost:3000/login
을 쳐서 들어가게 만들진 않는다는 얘기다. 그런 사이트가 있다면 아무도 안 쓸듯.
그래서 보통은 <a>
태그를 많이 쓰는데 그냥 그걸 <Link>
가 대신해준다고 보면 된다.
<div>
<ul>
<li>
<Link to="/">홈</Link>
</li>
<li>
<Link to="/about">어바웃</Link>
</li>
</ul>
<Route path="/" component={Home} exact />
<Route path="/about" component={About} />
</div>
App.js
를 다음과 같이 작성하게 되면 a
태그를 쓴 것 처럼 다음 화면이 나온다.
홈 버튼을 누르면 localhost:3000
어바웃을 누르면 localhost:3000/about
으로 이동한다.
그럼 라우팅 Route
에 따라 현재 주소가 localhost:3000/about
면 component={About}
이므로 About
컴포넌트를 출력한다.
하나의 라우트에 여러가지 패스를 정해줄 수가 있는데, 즉 URL
입력을 여러 개로 해도 동일한 컴포넌트가 렌더링 되도록 할 수 있다.
<Route path={['/about', 'hi']} component={About} />
위와 같이 적으면 http://localhost:3000/hi
일때도 About 컴포넌트가 렌더링 된다.
path
부분에는 배열이라는 자바스크립트 코드가 들어가므로 {}
로 감싸는 것을 잊어선 안 되겠다.
글의 길이가 좀 길어질 것 같아, 다음 글로 포스팅을 미루겠다.
감사합니다. 제가 찾던 내용이네요.
“'Link' is not defined react/jsx-no-undef” 에러나시는 분들은
import { Route, Link } from 'react-router-dom';
추가하시면 됩니다.