javascript 라우팅

otter·2022년 5월 13일
2
post-custom-banner

프로그래머스 과제 테스트 중 쇼핑몰 SPA를 풀다가, 라우팅 처리에 많은 고생을 했다.

React 에서는 react-router 을 통해 쉽게 처리할 수 있었는데 이걸 js 로 하려니까 어떻게 해야할지 막막했다. 정말 막막했다.
그래서 이 기회에 바닐라의 라우팅 처리를 정리해보고자 한다.

라우팅 처리가 필요한 이유

SPA 로 단일 페이지로 구현하면 브라우저의 앞으로가기 뒤로가기를 사용할 수 없다. 단일 페이지에서 이미 렌더링 되어있는 구성요소들만 바꿔주기 때문이다.

이는, 기존 사용자의 관점에서 좋지 않다. 앞으로가기 뒤로가기 버튼은 모든 사용자들이 계속해서 사용할 뿐더러 특히 뒤로가기가 안된다는 점은 좀 치명적이라고 생각한다.

React 에서는, react-router 를 통해서 라우팅처리를 했는데 JS 에서는 어떻게 라우팅 처리를 할 수 있을까?

프로그래머스 과제 테스트 : 쇼핑몰 SPA

  • 쇼핑몰 SPA 테스트에는 이미 서버 환경이 구성되어 있다.
  • path는 / , /products/ , /cart 가 있다.

window.location

// 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 출력하기.
}
  • 그럼에도, 이 코드는 단순히 현재 출력만 하고 있다.
  • 우리가 원하는, 특정 페이지에 렌더링이 될때 컴포넌트를 렌더링하지는 못한다.

window.history.pushState

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 이 구성되어 있어야 정상적으로 작동된다.
  • 어떻게 보면 서버방식과 혼합되어 있다.

window.history.popState()

  • 뒤로가기를 하려면, 이 메서드를 실행한다.
  • 현재 history state 가 가지고 있는 마지막 요소를 pop 하는데,
  • pop 을 하고 this.route 를 다시 실행한다.
  • this.route 에 따라서, 새로운 페이지가 렌더링 된다.

생각들

  • React 로 아무생각없이 구현하던 route 가 위의 기능을 이용하고 있다고 한다.
  • 서버환경을 미리 구성해주는 것도 중요하고, 특정 페이지로 로드할때 새로운 컴포넌트를 출력하는 것도 중요하고.. rest api 도 중요하고..
profile
http://otter-log.world 로 이사했어요!
post-custom-banner

0개의 댓글