블랙커피 Vanilla JS 문벅스 카페 메뉴 앱 만들기 섹션 3 회고

HYl·2022년 6월 9일
0

step2 요구사항 - 상태 관리로 메뉴 관리하기

  • localStorage에 데이터를 저장하여 새로고침해도 데이터가 남아있게 한다.
  • 에스프레소, 프라푸치노, 블렌디드, 티바나, 디저트 각각의 종류별로 메뉴판을 관리할 수 있게 만든다.
  • 페이지에 최초로 접근할 때는 에스프레소 메뉴가 먼저 보이게 한다.
  • 품절 상태인 경우를 보여줄 수 있게, 품절 버튼을 추가하고 sold-out class를 추가하여 상태를 변경한다.

localStorage에 메뉴 상태를 저장하여 관리하기 - 메뉴 추가하기

const $ = (selector) => document.querySelector(selector);

const store = {
 setLocalStorage(menu) {
   localStorage.setItem('menu', JSON.stringify(menu));
 },
 getLocalStorage() {
   JSON.parse(localStorage.getItem('menu'));
 },
};

function App() {
  this.menu = {
   espresso: [],
   frappuccino: [],
   blended: [],
   teavana: [],
   desert: [],
 };
 this.currentCategory = 'espresso';
 this.init = () => {
   ...
 };
 ...
 const render = () => {
   const template = this.menu[this.currentCategory]
     .map((item, index) => {
       return `
       <li data-menu-id="${index}" class="menu-list-item d-flex items-center py-2">
         <span class="w-100 pl-2 menu-name ${
           item.soldOut ? 'sold-out' : ''
         }">${item.name}</span>
         <button
           type="button"
           class="bg-gray-50 text-gray-500 text-sm mr-1 menu-sold-out-button"
         >
           품절
         </button>
         <button
           type="button"
           class="bg-gray-50 text-gray-500 text-sm mr-1 menu-edit-button"
         >
           수정
         </button>
         <button
           type="button"
           class="bg-gray-50 text-gray-500 text-sm menu-remove-button"
         >
           삭제
         </button>
       </li>`;
     })
     .join('');

   $('#menu-list').innerHTML = template;
   updateMenuCount();
 };
   
 const addMenuName = () => {
   if ($('#menu-name').value === '') {
     alert('값을 입력해주세요.');
     return;
   }
   const menuName = $('#menu-name').value;
   this.menu[this.currentCategory].push({ name: menuName });
   store.setLocalStorage(this.menu);
   render();
   $('#menu-name').value = '';
 };
}

// App(); 
const app = new App();  

localStorage에 사용될 상태를 관리하기 위하여 this.menu를 선언하였다. 이 과정에서 처음에는 App을 호출할 때 단순히 App() 으로 호출을 해주어, 함수 내부에서 this가 undefined로 출력이 되었다. 단순히 선언만 한 함수는 컨텍스트가 없기 때문이다. 객체 인스턴스로는 만들어지지 않은 상태여서 실체가 없으므로 함수 내부에서 this는 undefined로 호출이 되는 상태였다.

이러한 문제점을 해결하기 위하여 new 키워드와 함수를 사용해서 객체를 생성해주었다. const app = new App();
이제 함수 내부에서 this는 App {} 이다. this가 가리키는 대상이 바뀐 이유는 함수 App을 바탕으로 한 객체가 만들어졌기 때문이다.

Q. 함수 선언 시, this로 선언한 함수와 화살표 함수의 차이 ?

this는 여러 의미 중, "객체 자신을 가리킨다" 라는 것이 대표적이다. 그런데 위의 코드 중에서 this로 선언한 함수와 const변수에 화살표 함수로 선언한 함수가 있다.

this로 선언한 함수의 경우, 해당 this가 포함된 function을 "const app = new App()"과 같이 새로운 객체를 만들었을 때 app.render()와 같이 "." 을 이용하여 외부에서 내부 메서드를 이용하기 위해 사용하는 경우이다.
( => 메소드(객체의 속성에 할당된 함수)는 App 함수의 컨텍스트(this)에 직접 연결되어 있다. App 함수로 객체가 만들어지면 메서드도 그 객체에 포함된다. 서로 동일한 컨텍스트를 공유하는 개념이라고 볼 수 있다. )

그러나 함수 안에서 const 변수에 화살표 함수를 선언한 경우 app.render()와 같이 외부에서 사용할 수 없다.
( => 화살표 함수로 생성된 함수는 컨텍스트를 가지지 않으며 객체 생성을 위한 constructor도 없어서 new 키워드로 객체를 생성할 수 없다. 화살표 함수 내부에서 this는 그 함수를 포함하고 있는 객체 인스턴스를 가리킨다. )

참고 : https://blog.rhostem.com/posts/2018-07-20-this-in-javascript


회고

문법적으로 this에 대하여 공부를 익숙하게 했다고 생각을 했었는데 실전에 닥쳐보니 아직 헷갈리는 개념들이 많았다. 이번 기회를 통하여 다시 한번 this에 대해 복습을 하며 정리를 하는 시간을 가져서 좋았다.

이번 섹션에서는 상태 관리의 중요성을 통하여 재사용을 극대화 할 수 있는 방법을 새롭게 알 수 있었다. react에서는 익숙한 개념이었지만, 이것을 하나하나 구현해가며 동작 원리를 알 수 있다는 것이 새로웠고 자바스크립트에 한 발짝 더 다가간 느낌이었다.

store에 함수를 모아 관리하는 방법과 파일 분리, 여러 개의 if문으로 조건을 걸었을 때, return을 걸어주어 해당 조건 이외의 불필요한 연산들을 방지하여 사이트 이펙트와 버그를 방지하는 것 등 리팩토링을 가졌던 시간도 매우 유익했다.

profile
꾸준히 새로운 것을 알아가는 것을 좋아합니다.

0개의 댓글