일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- SCSS forward
- KDT 프로그래머스 데브코스 프론트엔드
- 리스트 렌더링
- netlify redirect
- vue mixin
- vuex map
- 프로그래머스 프론트엔드 데브코스
- 쌓임맥락
- git 같은계정 다른 컴퓨터
- flex
- SCSS import
- 프로그래머스 K_Digital Training
- SCSS extend
- vue 지역 컴포넌트
- SCSS use
- 리액트
- 다른컴퓨터에서 git사용
- react next
- 이벤트 수식어
- KDT 프로그래머스
- vue 이벤트 수신
- 프로그래머스 데브코스
- postcss
- 폼 입력 바인딩
- 프로그래머스 데브코스 프론트엔드
- 고양이 사진 검색기
- nextjs사용법
- Spacer
- Vue
- intersection opserver
- Today
- Total
혼자 적어보는 노트
프로그래머스 데브코스 - 노션 과제 피드백 본문
멘토님께 피드백을 받은지는 좀 되었지만 연속되는 과제와 강의^^; 로 조금 늦게 작성을 하게 되었다.
받은 피드백을 다시 한번 상기시키기 위해 적으면서 기록을 해보려고 한다.
1. 마크다운 shortcut 부분 코드 수정
✍ 기존 코드
export const EditorShortcut = (text) => {
let tag;
if (/^#\s/.test(text)) {
// #
tag = document.createElement("h1");
tag.innerText = text.substring(1);
return tag;
} else if (/^##\s/.test(text)) {
// ##
tag = document.createElement("h2");
tag.innerText = text.substring(2);
return tag;
} else if (/^###\s/.test(text)) {
// ###
tag = document.createElement("h3");
tag.innerText = text.substring(3);
return tag;
} else {
return false;
}
};
text를 받아와서 처리하는 부분이 조금 반복된다고 느끼기는 했었는데
어떻게 처리를 할 지 고민을 했던 부분이었었다.
멘토님께서 shortcut정보를 한 군데에 모아놓고 관리를 하는게 좋을 것 같다고 피드백을 받았다.
✅ 수정된 코드
const shortcutMap = [
{ regex: /^#\s/, tagName: "h1" },
{ regex: /^##\s/, tagName: "h2" },
{ regex: /^###\s/, tagName: "h3" },
];
export const EditorShortcut = (text) => {
let tag;
const shortcut = shortcutMap.find((item) => item.regex.test(text));
if (shortcut) {
const remove = text.length - 1;
tag = document.createElement(shortcut.tagName);
tag.innerText = text.substring(remove);
return tag;
} else {
return false;
}
};
shortcut의 내용을 보기 쉽게 정리하고 해당 데이터를 토대로
EditorShortcut 함수에서 중복 코드 없이 처리하는 방식으로 변경했다.
subString을 하는 부분도 다시 생각해보니 text의 length로 처리해도 될 듯 하여 수정했다.
이전보다는 조금은 보기 편해졌다 😊
2. title변경 부분 Debounce 주기 낮추기
Editor에서 title 변경 시 Document List에서 보여지는 title부분도 변경되게 적용을 했었는데
Editor에 걸어놓은 디바운스와 같은 주기여서 약간의 딜레이가 있었다.
✍ 기존 코드
onEditing: (document) => {
debounce(async () => {
await fetchEditDocument(document);
changeTitle();
}, 1000);
},
분리를 해보려고 살펴보니, Title과 content부분의 수정이 일어났을 때
동일한 onEditing함수를 호출하다보니
content를 변경하는데도 title을 실시간으로 변경시키는 changeTitle을 호출 했다.
✅ 수정된 코드
onEditContent: (document) => {
debounce(async () => {
await fetchEditDocument(document);
}, 1000);
},
onEditTitle: (document) => {
debounce(async () => {
await fetchEditDocument(document);
changeTitle();
}, 300);
}
코드를 2개로 분리하여 처리했다.
중복되는 함수가 있어서 인자로 document와 title과content를 구분할수 있게 작성을 하려 했지만
로직이 조금 복잡해 지는 듯 하여 조금 직관적으로 작성했다.
3. 헬퍼 함수 만들어보기
class가 있는 엘리먼트를 생성할 때 util함수로 빼서 생성을 했는데
class를 추가/제거 하는 것도 간단하게 만들어서 사용하면 좋을 것 같다는 피드백을 받았다.
✍ 기존 코드
$sidebar.classList.remove("hide");
$container.classList.add("hide");
✅ 수정된 코드
removeClass($sidebar, "hide");
addClass($editorContainer, "hide");
코드길이는 비슷하지 않을까? 라고 생각했는데
행위에 대해 앞부분에 명시적으로 작성이 되어있다보니 확실히 가독성이 좋다는 느낌을 받았다.
[util/helper.js]
export const addClass = (element, className) => {
element.classList.add(className);
}
export const removeClass = (element, className) => {
element.classList.remove(className);
}
4. 템플릿 리터럴 수정
post의 list를 보여주는 함수 내부의 템플릿 리터럴이 조금 복잡해져서
문자열을 반환하는 함수를 짜보기로 했다.
✍ 기존 코드
const createPost = (documents, depth) => {
const MAX_DEPTH = 5;
const POST_PADDING = depth * 10;
const selected = getItem(SELECTED_DOCUMENT, null);
return `
${documents
.map(({ id, title, documents }) => {
const isOpen = (openList && openList[id]) || false;
return `<li class="post__item" data-id="${id}">
<div class="item__content ${selected && selected.id == id ? "selected" : ""}"
style="padding-left:${depth === MAX_DEPTH ? POST_PADDING + 10 : POST_PADDING}px">
${depth < MAX_DEPTH ? `<button class="item__button--toggle"> ${isOpen ? "▼" : "▶"}</button> ` : ""}
<div class="item__title">${title ? title : "제목 없음"}</div>
<div class="item__buttons">
<button class="item__button--remove"><i class="fa-solid fa-trash-can"></i> </button>
${depth < MAX_DEPTH ? `<button class="item__button--add"><i class="fa-solid fa-plus"></i></button> ` : ""}
</div>
</div>
${
isOpen
? documents.length > 0
? `<ul>${createPost(documents, depth + 1)}</ul>`
: `<ul><li class="empty-post-message"> <span>하위 페이지가 없습니다</span></li> <ul>`
: ""
}
</li>
`;
})
.join("")}
`;
};
위 코드를 작성할 당시에도 되게 복잡하다고 느끼기는 했었다.
✅ 수정된 코드
const toggleBtn = (isOpen) => {
return `<button class="item__button--toggle"> ${isOpen ? "▼" : "▶"}</button>`;
}
const AddDocumentBtn = () => {
return '<button class="item__button--add"><i class="fa-solid fa-plus"></i></button>';
}
const childDocuments = (documents, depth) => {
if(documents.length > 0){
return `<ul>${createPost(documents, depth + 1)}</ul>`;
}
return `<ul><li class="empty-post-message"> <span>하위 페이지가 없습니다</span></li> <ul>`;
}
const createPost = (documents, depth) => {
const MAX_DEPTH = 5;
const POST_PADDING = depth * 10;
const selected = getItem(SELECTED_DOCUMENT, null);
return `
${documents
.map(({ id, title, documents }) => {
const isOpen = (openList && openList[id]) || false;
const paddingLeft = depth === MAX_DEPTH ? POST_PADDING + 10 : POST_PADDING;
const isSelected = selected && selected.id == id ? "selected" : "";
return `
<li class="post__item" data-id="${id}">
<div class="item__content ${isSelected}" style="padding-left:${paddingLeft}px">
${depth < MAX_DEPTH ? toggleBtn(isOpen) : ""}
<div class="item__title">${title ? title : "제목 없음"}</div>
<div class="item__buttons">
<button class="item__button--remove"><i class="fa-solid fa-trash-can"></i> </button>
${depth < MAX_DEPTH ? AddDocumentBtn() : ''}
</div>
</div>
${isOpen ? childDocuments(documents, depth + 1) : "" }
</li>
`;
})
.join("")}
`;
};
조건에 따라 다른 값을 반환하는 부분들은 함수로 처리해서 조금 정리를 해보았지만
아직은 조금 복잡한 것 같아서 다시 한번 더 시도해봐야 될 것 같다.
5. tagName/nodeName 비교 시 유틸함수로 변경
코드 내에 tagName이나 nodeName을 비교하는 부분들이 있었는데
유틸성 함수로 만들어서 사용해도 좋을 것 같다는 피드백을 받았다.
✍ 기존코드
event.target.tagName === "I" ? e.target.closest("button") : e.target;
✅ 수정된 코드
compareName(e.target.tagName, "I") ? e.target.closest("button") : e.target;
export const compareName = (name, text) => {
if(name === text){
return true;
}
return false;
}
💡 tagName과 nodeName의 차이
태그이름을 확인하는 프로퍼티인 tagName과 nodeName의 차이가 궁금해서 알아보니,
tagName은 Element에만 존재하고 nodeName은 모든 Node에 존재한다고 한다.
그 차이는 document와 주석 노드에서 확인할 수 있다.
<body><!-- 주석 -->
<script>
console.log( document.body.firstChild.tagName ); // undefined
console.log( document.body.firstChild.nodeName ); // #comment
console.log( document.tagName ); // undefined
console.log( document.nodeName ); // #document
</script>
</body>
Element node만을 확인하는 목적이라면 둘 다 사용해도 된다.
✍ 느낀 점
코드 리뷰는 매우 좋은 것 같다. 내 코드 뿐만 아니라 다른사람들이 받은 코드 리뷰를 보고도
다시 한번 생각해보는 기회가 생긴다. 그리고 무조건 적용을 직접 해보는 것이 좋은 것 같다.
하는 과정에서도 또 다른 방법들이 생각나기도 하고 적용해보면서 궁금한 부분들이나
팀원들과 논의해 볼 주제들이 생기기도 하고 여러모로 유익한 시간이었다!
'스터디' 카테고리의 다른 글
프로그래머스 데브코스 TIL - Day 37 (0) | 2022.05.11 |
---|---|
프로그래머스 데브코스 TIL - Day 36 (0) | 2022.05.11 |
프로그래머스 데브코스 TIL - Day 35 (0) | 2022.05.09 |
프로그래머스 데브코스 TIL - Day 34 (0) | 2022.05.06 |
프로그래머스 데브코스 TIL - Day 33 (0) | 2022.05.04 |