[ Vanilla JS ] arrow function으로 컴포넌트 만들기

bepyan·2022년 2월 6일

arrow function 답게 간편하게 앱을 만들어 보자.

컴포넌트의 싸이클

setup. 초기 세팅한다.
util. 사용될 함수를 작성한다.
setEvent. 이벤트 등록한다.
mounted. 추가적인 기능을 수행한다.

상태 관리 및 리렌더링은 싸이클에서 관리하지 않는다.
추후에 Observer 패턴을 활용해서 직접 상태를 관리하자.


예시

import { RecentlyViewedStore } from "../../stores";
import { homeState } from "./_state";

export const AddedList = () => {
  // setup. 초기 세팅한다.
  const root = document.createElement("div");
  root.innerHTML = `
    <h5>등록된 아이템 목록</h5>
    <div class="added__wrapper"></div>
  `;
  const itemList = root.querySelector(".added__wrapper");

  // util. 사용될 함수를 작성한다.
  const renderItemList = () => {
    itemList.innerHTML = `
        ${homeState.list
          .map((name) => `<span class="added__item">${name}</span>`)
          .join("")}
    `;
  };

  // setEvent. 이벤트 등록한다.
  root.addEventListener("click", (e) => {
    const isItem = e.target.classList.contains("added__item");
    if (isItem) {
      RecentlyViewedStore.dispatch("ADD_ITEM", { text: e.target.innerText });
    }
  });
  
  
  // mounted. 추가적인 기능을 수행한다.
  renderItemList();
  homeState.subscribe(renderItemList);

  return root;
};


리렌더링될 요소를 파악해서 별도로 렌더링 관리한다.
vanilla의 장점은 내가 원하는대로 렌더링을 관리할 수 있다는 점이다.
상태 변경에 따라 변경이 된 부분만 리렌더링이 진행되도록 하자. ( Observer 패턴 활용 )



이벤트를 등록할 때 최대한 버블링을 잘 활용하자.
className === ''이 아닌 classList.contains을 사용하는 것은 덤! ( 여러 클래스 이름을 사용할 수 있기에 )



코드 위치가 일관적이어야 한다.
같은 스코프에서 모든 라이프싸이클이 담겨지기에 파일마다 위치가 다르면 유지보수하기 굉장히 힘들다.
ex) subscribe 관련 작업 항상 최하단에서 한다.



DOM API를 최대한 잘 활용해야 한다.
DOM의 기능이 정말 많이 있다.
DOM 관련 closest insertAdjacentHTML ...
이벤트 관련 onsubmit keydown ontransitionend ...



최대한 컴포넌트를 잘게 쪼개자.



여러 컴포넌트

import { HomeForm } from "./HomeForm";
import { AddedList } from "./AddedList";
import { RecentlyViewedList } from "./RecentlyViewedList";

export const HomePage = () => {
  const app = document.querySelector("#app");

  app.appendChild(HomeForm());
  app.appendChild(AddedList());
  app.appendChild(RecentlyViewedList());
};

만든 컴포넌트는 appendChild을 통해서 추가한다. innerHTML로 추가하게 되면 등록한 event가 실종된다..



전체 코드 참고

profile
https://bepyan.me/ <<< 블로그 이전했습니다.

0개의 댓글