프론트엔드 개발을 위한 자바스크립트 [스터디/10기] 1주차 회고_피드백 반영 코드편

Derek·2021년 2월 1일
0

Programmers_JS_Study_FE

목록 보기
4/6
post-thumbnail

안녕하세요, Derek입니다.

Mission 1 게시물 후, 제 코드 정리편에 이어 마지막 피드백 내용을 포스팅해보려고합니다.

(어서오시죠)

바로 시작해보겠습니다!


1. Code Review 내용

여기를 보시면 아시겠지만, 제가 받은 feedback 의 내용은 다음과 같습니다.

  1. 클래스/생성자 함수의 이름은 관용적으로 대문자로 시작한다.
  2. class 하나만 있는 파일은 파일 이름과 class 이름을 같게하자.
  3. 함수나 메소드의 이름은 동사로 시작하는게 좋다.
  4. innerHTML 은 한번에 업데이트하자. forEach 를 통해 배열을 접근하며 매번 업데이트를 하면 리렌더링이 일어난다.
  5. 삼항연산자는 너무 복잡해지면 지양하자. 짧은 코드가 좋은게 아니라 보기 좋은 코드가 좋은 코드다.
  6. forEach 구문보다는 map 과 join 을 사용해서 구현해보길 바란다.
  7. 컴포넌트 를 재설계해보자.
  8. validation 함수안 조건들을 && 연산자로 나열하지말고 찢자.

이를 반영한 코드는 다음과 같습니다.

2. index.js

역할

html 의 script 태그에 등록된 .js 파일로, 이 파일에서 프로그램이 시작됩니다.


가장 핵심인 ControlToDoList 클래스의 생성자를 통해 인스턴스를 만듭니다.
생성자는 3개의 인자를 받습니다. data, id, title 값을 받습니다.

코드

import {rawData, derekDoneRawData, derekToDoRawData} from "./data/todoRawDatas.js";
import {ControlToDoList} from "./class/ControlToDoList.js";

const toDoObj = new ControlToDoList(rawData, "todo-list", "TO Do List");

setTimeout(() => {
    toDoObj.setState([{text: "앞구르기", isCompleted: true}, {text: "뒷구르기", isCompleted: false}]);
}, 3000);

const derekToDoObj = new ControlToDoList(derekToDoRawData, "todo-list-derek", "Derek To Do List");
const derekDoneObj = new ControlToDoList(derekDoneRawData, "done-list-derek", "Derek Done List");

반영 내용

위 코드에서 발견할 수 있는 내용은 아래와 같습니다.

1) 클래스의 이름 대문자화.

controlToDoList 에서 ControlToDoList 로 바꾸었습니다. 이는 아래 ControlToDoList.js 에서도 확인 가능합니다.

2) 컴포넌트 재설계.

class 의 상속을 제거했습니다. 생성자 함수에 3가지 인자를 받도록하여 불필요한 상속을 제거했습니다.

생성자 함수에서 2번째 인자, 즉 todo-list , todo-list-derek , done-list-derek , 은 HTML 에서 data 를 렌더링할 divid 값입니다.

또한, 각각을 렌더링할때 h3 태그로 표시할 제목도 인자로 두었습니다.

3) 인스턴스 하는 구문으로 코드 종료.

validation 하거나 render , 그리고 에러처리를 생성자 함수 안에 구현시켜놓았습니다. 이는 3번에 정리하였습니다.

3. ControlToDoList.js

역할

data 의 적합성을 판단하는 checkDataForm , 렌더링하는 render 를 구현한다.


마지막 보너스 구현항목인 setState 함수도 구현했다.

코드

import {message} from "../constantValue/message.js";

class ControlToDoList {
    constructor(rawData, $todoId, toDoListTitle) {
        this.toDoRawData = rawData;
        this.todoListElement = document.getElementById(`${$todoId}`);
        this.toDoListTitle = toDoListTitle;
        this.checkDataForm(this.toDoRawData);
        this.render();
    }

    checkDataForm() {
        if(Array.isArray(this.toDoRawData) === false) {
            throw new Error(message.RAW_DATA_TYPE_INAPPROPRIATE);
        }
        if(!this.toDoRawData) {
            throw new Error(message.RAW_DATA_TYPE_INAPPROPRIATE);
        }
    }

    render() {
        const todoDataHTMLString = this.toDoRawData.map((rawData, index) => {
            return rawData.isCompleted 
            ? `<s>${index + 1}. ${rawData.text}</s></br>` : `${index + 1}. ${rawData.text}</br>`
        }).join("");

        this.todoListElement.innerHTML = `
        <h3>${this.toDoListTitle}</h3>
        ${todoDataHTMLString}
      `;
    }

    setState(nextData) {
        this.toDoRawData = nextData;
        this.checkDataForm();
        this.render();
    }
}

export {ControlToDoList} 

반영 내용

위 코드에서 발견할 수 있는 내용은 아래와 같습니다.

1) 함수의 이름은 동사로 시작한다.

validationData 에서 checkDataForm 으로 변경했습니다.

2) valid 절차를 && 로 잇지 아니하고 찢자.

checkDataForm 함수 내부에는 가독성이 좋게 두 개의 if 문으로 구현해놓았습니다.

3) innerHTML 은 한번에 업데이트하자.

4) forEach 대신 mapjoin 사용을 권장한다.

변수 todoDataHTMLString 를 사용하여 innerHTML 을 한번에 업데이트함으로써, 리렌더링을 최소화 했습니다.
그와 동시에 forEach 구문 대신 mapjoin 을 사용했습니다.

5) DOM 객체 변수는 앞에 $ 를 붙인다.

일종의 컨벤션인데, 아주 유용하게 쓰일것 같더라구요! 🎉


4. 생성자 함수

이는 한번 언급하고 넘어가는게 좋을 것 같습니다. :)

constructor(rawData, $todoId, toDoListTitle) {
        this.toDoRawData = rawData;
        this.todoListElement = document.getElementById(`${$todoId}`);
        this.toDoListTitle = toDoListTitle;
        this.checkDataForm(this.toDoRawData);
        this.render();
    }

(rawData를 설명하는 글 참고하길 바랍니다.)

rawData , id , title 를 생성자 함수에 인자로 집어넣었습니다. 이를 통해 클래스의 상속을 제거했습니다.

const toDoObj = new ControlToDoList(rawData, "todo-list", "TO Do List");
const derekToDoObj = new ControlToDoList(derekToDoRawData, "todo-list-derek", "Derek To Do List");
const derekDoneObj = new ControlToDoList(derekDoneRawData, "done-list-derek", "Derek Done List");

따라서 이렇게 간단하게 인스턴스화 할 수 있었습니다.

이는 코드의 재사용성을 늘린 점으로, 굉장한 이점으로 보였습니다.

또한 document 에 접근하여 DOM 객체를 생성하는 횟수도 최소화하는 것이 좋다는 것도 배웠답니다. 👍


피드백을 받고 나서 훨씬 코드가 간결하고 가독성이 좋아진 것 같더라구요.

다음 Mission 2Mission 1 을 업그레이드 하는 내용이였습니다!

2주차 내용도 피드백을 받고 나면 정리해서 포스팅 해보겠습니다 :)

감사합니다!😉

profile
Whereof one cannot speak, thereof one must be silent.

0개의 댓글