프로그래머스 과제 테스트 중 쇼핑몰 SPA를 풀다가, 라우팅 처리에 많은 고생을 했다.
React 에서는 react-router 을 통해 쉽게 처리할 수 있었는데 이걸 js 로 하려니까 어떻게 해야할지 막막했다. 정말 막막했다.
그래서 이 기회에 바닐라의 라우팅 처리를 정리해보고자 한다.
SPA 로 단일 페이지로 구현하면 브라우저의 앞으로가기 뒤로가기를 사용할 수 없다. 단일 페이지에서 이미 렌더링 되어있는 구성요소들만 바꿔주기 때문이다.
이는, 기존 사용자의 관점에서 좋지 않다. 앞으로가기 뒤로가기 버튼은 모든 사용자들이 계속해서 사용할 뿐더러 특히 뒤로가기가 안된다는 점은 좀 치명적이라고 생각한다.
React 에서는, react-router 를 통해서 라우팅처리를 했는데 JS 에서는 어떻게 라우팅 처리를 할 수 있을까?
/ , /products/ , /cart 가 있다.// window.location.pathname 을통해 현재 경로를 확인할 수 있다.
const { pathname } = location;
console.log(pathname);
// 현재경로를 확인한다.
if(pathname === '/web/') {
console.log('this is main')
}
// 해당경로로 들어가면, `this is main` 출력된다.
if(pathname === '/web/cart') {
console.log('this is cart');
}
// 해당경로로 들어가면 `this is cart`가 출력된다.
// 이런 방식으로 url마다 다른 컴포넌트를 출력해 줄 수 있다.
const ProductListPage = () => {
App.innerHTML = '';
App.innerHTML += `<h1>메인페이지 입니다.</h1>`;
}
if(pathname === '/web/') {
console.log('this is main')
ProductListPage();
// main page 출력하기.
}
function App(target) {
this.state = {
clickedId : null,
}
this.setState = (newState) => {
this.state = {...this.state, ...newState}
}
this.route = () => {
target.innerHTML = '';
if(window.location.pathname === '/web/') {
new ProductsListPage(target, onClick);
}
if(window.location.pathname.includes('product')) {
const [, , newPathId] = window.location.pathname.split('/')
new ProductDetailPage(target, newPathId);
}
}
const onClick = (event) => {
const clickedList = event.target.closest('li');
window.history.pushState({}, null, window.location.origin + `/products/${clickedList.id}`);
this.setState( {clickedId : clickedList.id} )
this.route();
}
this.route();
}
window.history.pushState 메서드를 통해서, 라우팅을 동적으로 실행할 수 있다.url 을 바꿔준다.route 함수에서, url 을 읽고 새로운 컴포넌트를 출력한다.url 이 구성되어 있어야 정상적으로 작동된다.history state 가 가지고 있는 마지막 요소를 pop 하는데,pop 을 하고 this.route 를 다시 실행한다.this.route 에 따라서, 새로운 페이지가 렌더링 된다.React 로 아무생각없이 구현하던 route 가 위의 기능을 이용하고 있다고 한다.rest api 도 중요하고..