프로그래머스 과제 테스트 중 쇼핑몰 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
도 중요하고..