라우터 - 화면 처리기 만들기

dev__bokyoung·2022년 9월 1일
0

해커뉴스 클론코딩

목록 보기
3/12
post-thumbnail

프롤로그

이번에는 한 화면 내에서 페이지가 전환 되는 것 처럼 보이게 만들어보려고 한다. (SPA) 이전까지의 코드에서는 appendChild 로 삽입하는 코드만 있었는데 한 화면 내에서 화면전환이 일어나게 보이려면 원래 있던 콘텐츠를 새로운 콘텐츠로 overWrite 해줘야한다. 라우터를 만드는 단계흐름을 살펴보자.

1. 구조 구축하기

container.innerHTML 에 새롭게 덮여씌여 지는 구조를 만들어 준다. 추가적으로, 코드를 작성하는 사람이 직관적으로 알아 볼 수 있도록 creatElement 를 이용해 구조를 만드는 것이 아니라 문자열을 사용해서 구조를 수정 해주었다.

목록이 나올 부분

const newsList = [];

newsList.push('<ul>');

for(let i = 0; i < 10; i++) {
  newsList.push(`
    <li>
      <a href="#${newsFeed[i].id}">
        ${newsFeed[i].title} (${newsFeed[i].comments_count})
      </a>
    </li>
  `);
}

newsList.push('</ul>');

container.innerHTML = newsList.join('');

문자열을 사용해서 만들 때 위와 같이 ul 태그li 태그 를 반복해서 넣어야 하는 구조라면 하드코딩으로 하게 되면 비효율적이 되게 된다. 그래서 반복문을 사용해야 하는데 이때 자주 사용하는 것이 배열구조를 많이 사용한다고 한다.

  1. 빈 배열을 하나 만들고
  2. <ul> 을 넣는다.
  3. 그리고 반복문으로 li 구조를 만들어서 배열에 push 한다.
  4. 마지막에 </ul>push 한다.
  5. 그리고 DOM 에 그려 줄 때에는 배열에 담긴 요소들을 하나로 합쳐서 그려줘야 한다.
  6. join 을 사용하게 되는데 이때 기본적으로 합칠 때 , 로 합쳐지게 되는데 ,는 필요없으니 빈값을 넣어준다.

상세페이지가 나올 부분

window.addEventListener('hashchange', function() {
  const id = location.hash.substr(1);

  const newsContent = getData(CONTENT_URL.replace('@id', id))

  container.innerHTML = `
    <h1>${newsContent.title}</h1>

    <div>
      <a href="#">목록으로</a>
    </div>
  `;
});

2. 함수 분리

가장 간단한 게시판 구조를 생각해보자. 게시글 목록이 나오고, 사용자가 게시글을 클릭하면 상세 게시글을 보게 된다. 그리고 뒤로 돌아가기를 눌렀을 때 다시 목록화면이 나와야 한다.

이렇게 화면을 왔다갔다 할 수 있게 중계(전환)하는 것을 라우터 라고 한다. 라우터를 만들기 위해서는 하나로 묶여 있는 코드 즉, 함수를 실행시켜야 하는데 현재의 코드는 함수로 묶여 있는 코드가 아니다. 그래서 기능별로 함수로 분리를 시키자.

함수는 기능을 알아 볼 수 있도록 직관적으로 작성하는 것이 좋다.

피드(목록)

function newsFeed() {
  const newsFeed = getData(NEWS_URL);
  const newsList = [];

  newsList.push('<ul>');
  
  for(let i = 0; i < 10; i++) {
    newsList.push(`
      <li>
        <a href="#${newsFeed[i].id}">
          ${newsFeed[i].title} (${newsFeed[i].comments_count})
        </a>
      </li>
    `);
  }
  
  newsList.push('</ul>');
  
  container.innerHTML = newsList.join('');
}

상세

상세페이지 피드는 이벤트 핸들러에 묶여 있었다. 그래서 함수로 만들고 따로 분리를 시켜 주었다.

function newsDetail() {
  const id = location.hash.substr(1);
  const newsContent = getData(CONTENT_URL.replace('@id', id))

  container.innerHTML = `
    <h1>${newsContent.title}</h1>

    <div>
      <a href="#">목록으로</a>
    </div>
  `;
}

window.addEventListener('hashchange', newsDetail);

3. 라우터 작성

이제 화면 전환을 구현해보자.

  • 우선 뉴스피드와 뉴스디테일을 함수로 모두 묶어 놨으니 첫 화면에서 한번 쯤은 뉴스피드 함수를 불러줘야 한다.
  • 이벤트가 (hashchage) 일어 났을 때에도 화면 전환이 일어나야 하니까 브라우저 입장에서는 언제 어떤 피드를 불러줘야 하냐도 고려해야한다.
function router() {
  const routePath = location.hash;

  if (routePath === '') {
    newsFeed();
  } else {
    newsDetail();
  }
}

window.addEventListener('hashchange', router);

router();

location.hash 를 잡아서 그 값에 따라 어떤 화면을 보여 줄 지 나뉘었다. 화면 전환이 일어나는 이벤트에는 라우터 함수를 연결해주면 newsDetail 함수로만 고정되지 않게 된다.

4. 전체 코드

const container = document.getElementById('root');
const ajax = new XMLHttpRequest();
const content = document.createElement('div');
const NEWS_URL = 'https://api.hnpwa.com/v0/news/1.json';
const CONTENT_URL = 'https://api.hnpwa.com/v0/item/@id.json';

function getData(url) {
  ajax.open('GET', url, false);
  ajax.send();

  return JSON.parse(ajax.response);
}

function newsFeed() {
  const newsFeed = getData(NEWS_URL);
  const newsList = [];

  newsList.push('<ul>');
  
  for(let i = 0; i < 10; i++) {
    newsList.push(`
      <li>
        <a href="#${newsFeed[i].id}">
          ${newsFeed[i].title} (${newsFeed[i].comments_count})
        </a>
      </li>
    `);
  }
  
  newsList.push('</ul>');
  
  container.innerHTML = newsList.join('');
}

function newsDetail() {
  const id = location.hash.substr(1);
  const newsContent = getData(CONTENT_URL.replace('@id', id))

  container.innerHTML = `
    <h1>${newsContent.title}</h1>

    <div>
      <a href="#">목록으로</a>
    </div>
  `;
}

function router() {
  const routePath = location.hash; //화면을 전환하는 기준 값 

  if (routePath === '') {
    newsFeed();
  } else {
    newsDetail();
  }
}

window.addEventListener('hashchange', router);

router();

에필로그

뭔가 강의를 듣다 보면 처음부터 함수로 작성하는게 아니라 약간 원시적인 코드부터 시작해서 점점 발전하는 코드를 보여준다. 함수를 사용하면 왜 좋은지, 이런 코드 보다 저런 코드는 어떨지 등등의 생각포인트를 알려주는데 좋은 것 같다. 해커뉴스 클론코딩 시리즈 말고 이전에 작성했던 리액트 30 시리즈에서는 사실 너무 깔끔한 코드로 코딩을 하는데 나같은 아직 비기너들은 음 그렇군의 수준이기 때문이다. 뭔가 처음부터 바로 그런 코드를 작성하기 까지는 시간이 꽤 걸리는 데 이때 이런 코드의 흐름을 알고 가면 정말 좋을 것 같다. 결론은 이 강의 좋고 시간 아깝지 않다. !

profile
개발하며 얻은 인사이트들을 공유합니다.

0개의 댓글