라우팅 하기 - 본격적으로 세팅!

YEONGHUN KO·2021년 12월 27일
0

JAVASCRIPT - BASICS

목록 보기
15/27
post-thumbnail
post-custom-banner

그냥 실험용으로 간단하게 만들어 보았다. trend, upcoming을 클릭하고 page를 클릭하면 url이 ?trend?page=1 로 바뀌게 했다.

만약 search term이 있으면 ?searching?query='searchTerm'?page=1 요런식으로 주소가 바뀐다. 그리고 데이터는 따로 가공해서 pushState로 넘겨주고 popstate 이벤트를 통해 뒤로, 앞으로 갈때마다 넘겨받는다.

<form>
    <input type="text" />
    <button type="submit">button</button>
  </form>
  <div class="wrap">
    <div class="container">

      <!-- end of row -->

      <div class="row">
        <div class="columns twelve">
          <div class="programs">
            <button class="trend">trend</button>
            <button class="upcoming">upcoming</button>
          </div>
        </div>
      </div>
      <!-- end of row -->

      <div class="row">
        <div class="twelve columns">
          <h4>Programs List</h4>
        </div>
      </div>
      <!-- end of row -->

    <!-- end of container -->
  </div>
  <!-- end of wrap -->
  <footer id="pagination">
    <ul>
      <li class="active">1</li>
      <li class="no">2</li>
      <li class="no">3</li>
      <li class="no">4</li>
    </ul>
  </footer>

const $buttons = document.querySelector('.programs');
const $pages = document.querySelector('#pagination');
const $form = document.querySelector('form');
const $input = document.querySelector('input');

let state = {
  dbType: null,
  currentPage: 1,
  searchingTerm: null,
};

const routerDispatcher = ({ dbType, searchingTerm, currentPage }) => {
  window.dispatchEvent(
    new CustomEvent('router-change', {
      detail: {
        dbType,
        searchingTerm,
        currentPage,
      },
    })
  );
};

const initRouter = () => {
  window.addEventListener('router-change', event => {
    const { dbType, searchingTerm, currentPage } = event.detail;
    const pushData = {
      dbType,
      searchingTerm,
      currentPage,
    };
    window.history.pushState(
      pushData,
      null,
      `?${dbType}${searchingTerm ? `?query=${searchingTerm}` : ''}${
        currentPage ? `?page=${currentPage}` : ''
      }`
    );
   
  });

  window.addEventListener('popstate', event => {
    if (event.state) {
      const { dbType, currentPage, searchingTerm } = event.state;
      state = { dbType, currentPage, searchingTerm };
      console.log(state);
      console.log(dbType, currentPage, searchingTerm);
    }
  });
};

//App
initRouter();

$buttons.addEventListener('click', e => {
  const { className } = e.target;
  if (className === 'trend' || className === 'upcoming') {
    state.dbType = className;
    routerDispatcher({ dbType: state.dbType });
  }
});

$pages.addEventListener('click', e => {
  const { nodeName, textContent } = e.target;
  if (nodeName === 'LI') {
    if (state.dbType) {
      state.currentPage = textContent;
      const { dbType, currentPage, searchingTerm } = state;
      if (dbType === 'searching') {
        routerDispatcher({ dbType, currentPage, searchingTerm });
      } else {
        routerDispatcher({ dbType, currentPage });
      }
    }
  }
});

$form.addEventListener('submit', e => {
  e.preventDefault();
  state.dbType = 'searching';
  state.searchingTerm = $input.value;
  state.currentPage = 1;
  const { dbType, currentPage, searchingTerm } = state;
  routerDispatcher({ dbType, currentPage, searchingTerm });
  $input.value = '';
});

우선 state객체를 만들어 안에 history에 들어갈 data를 정리한다.

그리고, initRouter로 커스텀 이벤트를 받아들일 준비를 한다. 또한, popstate까지 같이 세팅을 해주어 라우팅 준비를 완료한다.

이제 라우팅이 필요한 곳에 state를 업데이트 하고 , routerDispatcher를 불러들여 업데이트 된 state안에서 데이터를 필요에 따라 꺼낸 다음 선별적으로 pass한다.

그리고 popstate될때도 state까지 자동 업데이트 되도록 코드를 짜보았다.

사실, history와 popstate 이벤트 만으로도 라우팅을 구현할 수 있지만, 커스텀 이벤트를 사용해보고 싶어서 일단 적용해보았다.

이로써 SPA의 원리를 배웠다. 그리고 클라이언트에서 랜더링하는 CSR을 배웠다. 그럼 CSR과 서버단에서 랜더링하는 SSR의 차이점이 뭔지 다음글에서 알아보자.

profile
'과연 이게 최선일까?' 끊임없이 생각하기
post-custom-banner

0개의 댓글