지금까지는 리액트 문법에 대해 공부했다면, 이제는 한 페이지 안에서 여러 페이지가 동작하는 것처럼 보이는 리액트 라우터의 사용법을 공부한다.
리액트 라우터를 사용하기 위해서는 기본적인 뼈대 역할을 하는 react-router
와 실질적으로 라우터를 생성하는 react-router-dom
모듈을 설치해야 한다.
npm i react-router
npm i react-router-dom
설치한 리액트 라우터를 사용하려면 import
를 이용한 구조 분해 문법을 사용하면 되는데, 보통 BrowserRouter
나 HashRouter
를 사용한다. 이 외에도 StaticRouter
가 있는데, 일반적으로 서버 쪽에서 사용하기 때문에 웹에서는 잘 사용하지 않는다.
연결하고자 하는 페이지를 <BrowserRouter>
혹은 <HashRouter>
태그 안에 Route
태그를 이용해 생성한 컴포넌트를 연결해주면 된다. 리액트 라우터로 페이지를 연결할 때, <a>
태그를 이용하지 않고, <Link>
를 사용한다. <a>
태그를 사용하면 에러가 발생한다.
BrowserRouter
import NumberBaseball from '../3.숫자야구/NumberBaseball';
const Games = () => {
return (
<BrowserRouter>
<Link to="/number-baseball">숫자야구</Link>
<Route path="/number-baseball" component={NumberBaseball} />
</BrowserRouter>
);
};
✓주의
Hooks와 Class를 섞어 사용할 경우 리액트를 두 번 임포트하는 상황이 발생하기 때문에 둘 중 하나로 맞추어야 한다.
HashRouter
HashRouter
도 BrowserRouter
와 크게 차이가 없지만, 주소의 바로 뒤에 #/
이 추가된다. 해시 다음 부분이 브라우저가 담당하고 있기 때문에 서버 쪽은 이 부분에 관여하지 않는다. HashRouter
의 장점은 BrowserRouter
와 달리 새로고침을 해도 서버 쪽에서 오류가 나지 않고 동작한다는 것이다. 단점은 서버 쪽에서 브라우저 부분을 모르기 때문에 검색 엔진 면에서 불이익을 받는다. 실무에서는 이러한 이유때문에 HashRouter
는 잘 사용하지 않는다.
Switch와 exact
동적 라우팅을 사용할 때, 정적 라우팅의 주소와 일치하면 하나의 라우팅만 되는 것이 아니라 모든 정보가 라우팅된다. 이럴 때 특정 라우팅만 사용하게 하려면 리액트 라우터의 Switch
를 사용하면 된다. Switch
태그로 감싼 라우터는 여러 개의 주소가 일치해도 가장 첫번째만 라우팅이 된다.
<Switch>
<Route path="/game/:name" />
<Route path="/game/number-baseball" />
</Switch>
:name
자리에 number-baseball
이 와도 Switch
태그로 감싸져있기 때문에 가장 첫번째만 라우팅이 된다. 그러나 /
와 같이 상위 주소인 경우에는 브라우저 주소가 달라도 같은 주소로 취급하기 때문에 Switch
태그로 감싸져있어도 구분이 되지 않는다. 이럴 때 명확하게 사용하기 위한 문법이 exact
이다.
<Switch>
<Route path="/" />
<Route path="/game/:name" />
</Switch>
위 코드에서는 브라우저 주소가 ~/game/number-baseball
이어도 /
또한 같은 주소로 인식하기 때문에 Switch
태그로 감싸져 있어도 path
가 /
인 곳으로 라우팅이 된다.
<Route exact path="/" />
<Route path="/game/:name" />
path
앞에 exact
를 붙여주면 path
의 요소에 있는 주소와 정확하게 일치할 때에만 라우팅이 되므로 위와 달리 주소가 ~/game/number-baseball
이어도 path
가 /
인 곳은 라우팅이 되지 않는다.
변수를 할당할 때, 일반적으로 오른쪽에 있는 변수의 요소가 왼쪽의 있는 변수의 요소보다 많거나 같아야 한다.
interface Ironman {
name: string;
}
class Avengers {
name: string;
}
let i: Ironman;
i = new Avengers();
할당할 때 타입은 꼭 일치하지 않아도 된다. Ironman
과 Avengers
모두 name
이라는 공통된 요소를 가지고 있기 때문에 Ironman
으로 정의된 변수 i
에 Avengers()
를 할당할 수 있다.
interface Ironman {
name: string;
age: number;
}
class Avengers {
name: string;
}
let i: Ironman;
i = new Avengers(); // 에러
하지만 할당받는 변수의 타입 요소가 할당하려는 타입 요소보다 많은 경우, 할당이 불가능하다.
일반적으로 타입스크립트의 모듈 시스템은 자바스크립트 ES6+의 문법과 동일하다.
/* math.js */
export var pi = 3.14;
/* app.js */
import { pi } from './math.js' // 경로 삽입
console.log(pi) // 3.14