SDWoo
SDWoo의 개발일기
SDWoo
전체 방문자
오늘
어제
  • 분류 전체보기 (21)
    • 데브코스 (4)
    • TIL (13)
    • javascript (4)
    • react (0)
    • 알고리즘 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기

공지사항

인기 글

태그

  • Til
  • JavaScript
  • JavaScript #TIL #VanillaJS
  • intersectionobserver
  • Spread문법
  • Typing-Game
  • es6
  • 이벤트루프
  • 디스트럭처링할당
  • 신규 아이디 추천
  • 선형
  • addEventListener
  • javascrip
  • 제네레이터
  • 데브코스
  • 프로그래머스
  • linkedlist
  • vanillajs
  • deepdiv
  • 비동기
  • 무한스크롤
  • vanilaJS
  • 알고리즘
  • async/await
  • Promise
  • 호이스팅
  • cypress
  • RESTAPI 설계 원칙 #까먹지말것
  • This
  • 행맨

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
SDWoo

SDWoo의 개발일기

VanillaJS를 통한 자바스크립트 정리 1
데브코스

VanillaJS를 통한 자바스크립트 정리 1

2022. 10. 31. 22:55

허접하지만 맛있다

📖 오늘 배운 것

컴포넌트 방식으로 생각하기
- Simple Todo List 만들기

컴포넌트 방식으로 만드는 것은 어렵다

  • UI를 선언적으로 표현하기 위해 표현하는 부분들을 추상화 가능하다.
  • Header, TodoForm, TodoList, 그리고 이 세가지 컴포넌트들을 관리할 app
    • 각자를 하나의 단위로 보고 나눈다.
    • 이 모든 것을 하나로 합칠 app이 필요함
    • 이렇게 추상화를 진행해 놓으면 수정 단계에서 해당 화면에서 입력받는 것만 고치면 된다.

1. TodoList

  • 파라미터: target(어느 화면? 에 표시될 것인지 , append 될 것인지), state (todoLIst에 표현할 데이터)
  • 받은 파라미터들로 데이터를 계산하여 화면에 출력
function TodoList({$target, initialState}) {
    const $todoList = document.createElement('div');
    $target.appendChild($todoList);

    this.state = initialState;

    this.setState = (nextState) => {
        this.state = nextState;
        this.render(); // state가 바뀌고 화면을 바꿔주어야함
    }

    this.render = () => {
        $todoList.innerHTML = `
        <ul>
        ${this.state.map(({text}) => `<li>${text}</li>`).join('')}
        </ul>
        `
    }

    this.render(); // 맨 처음 rendering때 필요
}

2. TodoForm

  • 파라미터: target(위와 동일), onSubmit(input의 입력결과를 app으로 빼서 TodoList에 사용하여 직접적인 의존성을 가지지 않게 하기 위함)
  • 입력받은 밸류를 onSubmit 함수를 통해 app으로 뺀 후 TodoList에 전해줌
  • 입력받은 밸류를 localStorage에 저장
function TodoForm({$target, onSubmut}) {
    const $form = document.createElement('form');
    $target.appendChild($form);

    let isInit = false; // 목적성? 

    this.render = () => {
        $form.innerHTML = `
        <input type="text" name="todo"/>
        <button>add</button>
        `

        if(!isInit) {
            $form.addEventListener('submit', e => {
                e.preventDefault();

                const input = $form.querySelector('input[name=todo]');
                // 입력 후 밸류 초기화를 위함 
                const value = input.value;
                input.value = '';

                // value값이 빈 값일 경우 추가 안하기 위함
                if(value.length > 1) {
                    onSubmit(value);
                }
            })
            isInit = true;
        }
    }
    this.render();
}

3. Header

  • 파라미터: target(위와 동일), text (없어도 됨 솔직히 걍 이름 정해주기 위하)
function Header({$target, text}) {
    const $header = documenrt.createElement('h1');
    $target.appendChild($header);

    this.render = () => {
        $header.textContent = text;
    }
    this.render();
}

4. App

  • 파라미터: target (main에서 선언해서 뿌려줌), initialState(localStorage에서 받아온 todoList)
function App({$target, initialState}) {
    new Header({$target, text: 'Simple TodoList'});
    new TodoForm({$target, 
        onSubmit: (text) => {
            const nextState = [...todoList.state, {text}];

            todoList.setState(nextState);
            storage.setItem('todos', nextState);
        })
    const todoList = new TodoList({$target, initialState})
}

5. storage

  • 파라미터: window.localStorage (localStorage 를 사용하기 위함)
  • 즉시실행 함수(전역 오염을 최소화하기 위함)로 구현함
  • json 형태가 아닌 데이터가 올 수도 있으니 try/catch 문을 활용해 storage.js 에서 관리하기 위함
const storage = (function(storage) {
    const setItem = (key, value) => {
        try {
            storage.setItem(key,JSON.stringify(value));
        }catch (e) {
            console.log(e.message);
        }
    }
    const getItem = (key, defaultValue) => {
        try {
            const storageValue = storage.getItem(key);

            if(storageValue) {
                return JSON.parse(storageValue);
            }
            return defaultValue;
        }catch (e) {
            console.log(e.message);
            return defaultValue;
        }
    }
    const removeItem = (key) => {
        storage.removeItem(key);
    }

    return {
        setItem,
        getItem,
        removeItem
    }
})(window.localStorage)

이렇게 Simple TodoList 구현이 완료 되었다.

오늘 꼭 기억해야 할 것을 다시 적어보자

  1. 컴포넌트화를 하는 이유는? 추상화를 통해 코드 재사용성이나, 코드를 고칠 경우 해당 컴포넌트만 고치면 되는등 장점이 많다.
  2. 컴포넌트를 나누는 기준? 서로 의존성이 없는 경우에 가장 좋음. 화면을 기준으로 나눈 다음 모든 컴포넌트들을 App 컴포넌트에 넣어주어서 관리해도 됨
  3. 의존성을 최대한 없게 코드를 구성하자.
    => 컴포넌트 생성 파라미터에 다른 컴포넌트를 넣지말고, 콜백 함수를 통해 해당 데이터를 뽑아서 setState와 같은 함수로 App 컴포넌트에서 데이터들을 뿌려준다.
  4. form 에는 action이라는 속성이 있는데 없는 경우 디폴트 값으로 자기 자신의 url을 넣어주어 submit하는 경우 계속해서 새로고침이 되므로 e.prevenDefault()로 디폴트 작업들을 막아주어야 함

'데브코스' 카테고리의 다른 글

[VanillaJS] TodoList에 Drag & Drop 이벤트 적용시키기 (feat. taskQueue)  (0) 2022.11.24
VanillaJS를 통한 자바스크립트 정리 2  (0) 2022.11.02
프로그래머스 데브코스 2주차 회고록 😝  (0) 2022.10.31
    '데브코스' 카테고리의 다른 글
    • [VanillaJS] TodoList에 Drag & Drop 이벤트 적용시키기 (feat. taskQueue)
    • VanillaJS를 통한 자바스크립트 정리 2
    • 프로그래머스 데브코스 2주차 회고록 😝
    SDWoo
    SDWoo

    티스토리툴바