Mission 1 게시물 후, 제 코드 정리편에 이어 마지막 피드백 내용을 포스팅해보려고합니다.
(어서오시죠)
바로 시작해보겠습니다!
Code Review
내용여기를 보시면 아시겠지만, 제가 받은 feedback
의 내용은 다음과 같습니다.
- 클래스/생성자 함수의 이름은 관용적으로 대문자로 시작한다.
- class 하나만 있는 파일은 파일 이름과 class 이름을 같게하자.
- 함수나 메소드의 이름은 동사로 시작하는게 좋다.
- innerHTML 은 한번에 업데이트하자. forEach 를 통해 배열을 접근하며 매번 업데이트를 하면 리렌더링이 일어난다.
- 삼항연산자는 너무 복잡해지면 지양하자. 짧은 코드가 좋은게 아니라 보기 좋은 코드가 좋은 코드다.
- forEach 구문보다는 map 과 join 을 사용해서 구현해보길 바란다.
- 컴포넌트 를 재설계해보자.
- validation 함수안 조건들을 && 연산자로 나열하지말고 찢자.
이를 반영한 코드는 다음과 같습니다.
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");
위 코드에서 발견할 수 있는 내용은 아래와 같습니다.
controlToDoList
에서 ControlToDoList
로 바꾸었습니다. 이는 아래 ControlToDoList.js
에서도 확인 가능합니다.
class
의 상속을 제거했습니다. 생성자 함수에 3가지 인자를 받도록하여 불필요한 상속을 제거했습니다.
생성자 함수에서 2번째 인자, 즉 todo-list
, todo-list-derek
, done-list-derek
, 은 HTML
에서 data
를 렌더링할 div
의 id
값입니다.
또한, 각각을 렌더링할때 h3
태그로 표시할 제목도 인자로 두었습니다.
validation
하거나 render
, 그리고 에러처리를 생성자 함수 안에 구현시켜놓았습니다. 이는 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}
위 코드에서 발견할 수 있는 내용은 아래와 같습니다.
validationData
에서 checkDataForm
으로 변경했습니다.
valid
절차를 &&
로 잇지 아니하고 찢자.checkDataForm
함수 내부에는 가독성이 좋게 두 개의 if
문으로 구현해놓았습니다.
innerHTML
은 한번에 업데이트하자.forEach
대신 map
과 join
사용을 권장한다.변수 todoDataHTMLString
를 사용하여 innerHTML
을 한번에 업데이트함으로써, 리렌더링을 최소화 했습니다.
그와 동시에 forEach
구문 대신 map
과 join
을 사용했습니다.
DOM 객체
변수는 앞에 $
를 붙인다. 일종의 컨벤션인데, 아주 유용하게 쓰일것 같더라구요! 🎉
이는 한번 언급하고 넘어가는게 좋을 것 같습니다. :)
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 2
는 Mission 1
을 업그레이드 하는 내용이였습니다!
2주차 내용도 피드백을 받고 나면 정리해서 포스팅 해보겠습니다 :)
감사합니다!😉