간단한 코딩이었지만 코드량이 많아졌고 이런 작업을 해 봤기 때문에 jsx의 고마움(?)과 jsx를 사용하기 위해 늘 같이 다녔던 바벨의 존재를 조금 더 피부로 깨닫게 되었다.
바벨은 jsx 문법을 사용할 수 있도록 도와주는 컴파일러.
(더 자세히 말하자면 자바스크립트 최신 문법을 브라우저가 읽을 수 있는 구형 문법으로 바꿔주는 컴파일러이다)
웹팩은 수 많은 자바스크립트 파일들을 배포하기 좋은 형태로 묶어주는 툴.
(ESM, commonJS를 지원)
이런 cli 도움 없이 빌드부터 수작업으로 만들어보는 것이 작업물에 대한 이해도 측면에선 의미는 있겠지만 효율적인 면에서 봤을 때 '잘' 이용하는 것도 좋겠다는 생각이 들었다.
js, css 파일 외에 이미지 파일이나 폰트 파일의 경우도 src 폴더 밑에서 import
를 사용해 포함하는 것이 좋다. 왜냐면 웹팩에서 해시값을 이용해 url을 생성
해주기 때문에 파일의 내용이 변경되지 않으면 브라우저 캐싱 효과
를 볼 수 있기 때문이다.
pushState
, replaceState
함수와 popstate
이벤트만 있으면 클라이언트에서 라우팅 처리가 되는 단일 페이지 어플리케이션을 만들 수 있다.
import React, { useEffect, useState } from 'react';
function App() {
const [pageName, setPageName] = useState('');
const onChangePage = (pageName) => {
setPageName(pageName)
}
useEffect(() => {
window.onpopstate = function(event) {
onChangePage(event.state)
}
}, [])
const onClick1 = () => {
const pageName = 'page1';
window.history.pushState(pageName, '', '/page1');
onChangePage(pageName)
}
const onClick2 = () => {
const pageName = 'page2';
window.history.pushState(pageName, '', '/page2');
onChangePage(pageName)
}
return (
<div className="App">
<button onClick={onClick1}>page1</button>
<button onClick={onClick2}>page2</button>
{
!pageName && <Home />
}
{
pageName === 'page1' && <Page1 />
}
{
pageName === 'page2' && <Page2 />
}
</div>
);
}
function Home() {
return <>home</>
}
function Page1() {
return <>page1</>
}
function Page2() {
return <>page2</>
}
export default App;
브라우저 리스토리 api를 이용해서 페이지 라우팅 처리를 직접 구현할 수도 있지만 보다시피 코드량이 많다.
react-router-dom 패키지를 이용해 간략하게 줄여보자.
import React, { useEffect, useState } from 'react';
import {BrowserRouter, Route, Link} from 'react-router-dom';
function AppRouter() {
return (
<div className="App">
<BrowserRouter>
<div>
<Link to="/">home</Link>
<Link to="/photo">photo</Link>
<Link to="/rooms">rooms</Link>
</div>
<Route path="/" exact component={Home} />
<Route path="/photo" exact component={Page1} />
<Route path="/rooms" exact component={Page2} />
</BrowserRouter>
</div>
);
}
function Home() {
return <>home</>
}
function Page1() {
return <>page photo</>
}
function Page2() {
return <>page rooms</>
}
export default AppRouter;
같은 path 속성값을 갖는 Route 컴포넌트를 여러 번 작성하면 같은 화면에 작성한 컴포넌트들이 동시에 렌더링된다.