-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Mission4/김재현] - Project_Notion_VanillaJS #23
base: 3/#4_kimjaehyeon
Are you sure you want to change the base?
[Mission4/김재현] - Project_Notion_VanillaJS #23
Conversation
body: JSON.stringify(tempPost), | ||
}); | ||
|
||
// this.setState() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사용하지 않는 코드들은 제거해주세요 ㅎㅎ
|
||
throw new Error("API 처리중 뭔가 이상합니다!"); | ||
} catch (error) { | ||
alert(error.message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alert로 하게 되면 유저들이 이 정보를 보게 될거같은데 이 정보가 유저들이 인지할 필요가 있는 정보일까요?_?
const isNew = this.state.documentId === "new"; | ||
|
||
if (isNew) { | ||
const createdPost = await request("/documents", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아예 코드단에서는 request를 사용해서 url을 넘기는게 아니라 서비스 폴더를 하나 만들거나 해서 거기서 작성하도록 하는것도 좋아보여요.
request(/document); 를 예로 들면 그냥 createPost()같은 메서드를 만들어서 컴포넌트 레벨에서 사용하고 request나 url은 서비스 파일에서 쥐고 관리하는거져. 그럼 훨씬 코드가 직관적으로 보이고 url관리도 좋을것 같습니다.
$target: $content, | ||
initialState: post, | ||
onEditing: (post) => { | ||
if (timer !== null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
단지 이 함수 내에서만 사용하는 목적으로 디바운스를 만들었는데 유틸성함수로 뽑아내서 여러군데에서 쉽게 사용할 수 있도록 만들어보세요 ㅎㅎ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5) 타이머를 null로 사용한건 좋은 거 같아요! 분리 가능하다면 더 좋아질 것 같습니다! 😆
body: JSON.stringify(post), | ||
}); | ||
} | ||
}, 500); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
매직넘버는 상수화해서 사용하면 좋을것 같습니다 ㅎㅎ
|
||
if (pathname === "/") { | ||
await sideBar.setState(); | ||
await content.setState({ documentId: "new" }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요런 id도 계속 사용하는것 같아서 상수화 하는게 버그 방지에 좋을것 같습니다.
this.state = nextState; | ||
this.render(); | ||
contentEditor.setState( | ||
this.state.document || { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
document가 전역으로 있는 키워드이다보니까 다른 이름을 사용하는게 좀 더 좋아보여요!
$contentEditor.querySelector("[name=title]").value = this.state.title; | ||
$contentEditor.querySelector("[name=content]").value = this.state.content; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
돔에 접근하기 위한 목적이라면 별도로 name같은걸로 접근하는거 대신에 id를 사용하는게 좋아보입니다.
const $item = e.target; | ||
const { id } = $item.parentElement.dataset; | ||
|
||
if ($item.className === "item-load") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런 클래스이름들도 상수화해서 사용해주세요~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
리뷰 완료입니다~ 고생하셨어요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
재현님 과제 하시느라 고생 많으셨어요👏👏
이전 투두앱 과제 때보다 바닐라 자바스크립트 실력이 쑥쑥 느신 거 같아요👍👍
요즘 과제가 물밀듯이 나오는데😹 마지막까지 화이팅하세요 :)
const localStorage = window.localStorage; | ||
|
||
export const getItem = (key, defaultValue) => { | ||
try { | ||
const storedValue = localStorage.getItem(key); | ||
|
||
return storedValue ? JSON.parse(storedValue) : defaultValue; | ||
} catch (error) { | ||
return defaultValue; | ||
} | ||
}; | ||
|
||
export const setItem = (key, value) => { | ||
localStorage.setItem(key, JSON.stringify(value)); | ||
}; | ||
|
||
export const removeItem = (key) => { | ||
localStorage.removeItem(key); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
로컬스토리지 관련 로직은 따로 사용 안 하신 거 같네요!
만약 사용하신다면 setItem, removeItem 함수도 에러 처리를 위해 try, catch문으로 감싸주시는 게 좋을 거 같아요ㅎㅎ
|
||
this.route(); | ||
|
||
initRouter(() => this.route()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initRouter(() => this.route()); | |
initRouter(this.route); |
라우터 함수만 전달해도 될 거 같습니다!
title: "", | ||
content: "", | ||
}, | ||
onEditing, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이벤트 핸들러로 사용하시는 거니까 onEdit이나 onEditContent 처럼 on접두사 뒤에 동사형태가 좋을 거 같습니다ㅎㅎ
export default function SideBarItem(item) { | ||
return ` | ||
<li data-id="${item.id}"> | ||
<span class="item-load"> | ||
${item.title} | ||
</span> | ||
<button class="item-remove">-</button> | ||
<button class="item-add">+</button> | ||
<ul class="sidebar-list-ul"> | ||
${item.documents.length > 0 ? item.documents.map((item) => SideBarItem(item)).join("") : ""} | ||
</ul> | ||
</li> | ||
`; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
비구조할당으로 item에서 id, title, documents를 빼서 바로 사용해도 좋을듯 싶습니다ㅎㅎ
$sideBarList.addEventListener("click", async (e) => { | ||
const $item = e.target; | ||
const { id } = $item.parentElement.dataset; | ||
|
||
if ($item.className === "item-load") { | ||
push(`/documents/${id}`); | ||
|
||
return; | ||
} | ||
|
||
if ($item.className === "item-remove") { | ||
await request(`/documents/${id}`, { | ||
method: "delete", | ||
}); | ||
|
||
push(`/`); | ||
|
||
return; | ||
} | ||
|
||
if ($item.className === "item-add") { | ||
const tempPost = { | ||
title: "", | ||
parent: id, | ||
}; | ||
const createdPost = await request("/documents", { | ||
method: "post", | ||
body: JSON.stringify(tempPost), | ||
}); | ||
|
||
// this.setState() | ||
push(`/documents/${createdPost.id}`); | ||
} | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이벤트 핸들러 같은 경우 모든 케이스를 if문으로 분기하시는 방법은 좋지만, 로직이 조금 길어질 때는 if 안의 로직을 따로 함수로 분리하셔도 좋을 거 같아요😊😊
const post = { | ||
title: "", | ||
content: "", | ||
}; | ||
|
||
let timer = null; | ||
|
||
const contentEditor = new ContentEditor({ | ||
$target: $content, | ||
initialState: post, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
contentEditor의 초기값으로 post 변수를 만들어 넣어주셨는데, 이 post는 변수는 1회성으로 사용하시는 거 같아서 생성자 함수의 인자 initialState에 초기값을 직접 넣어주셔도 될 거 같고, 또 ContentEditor에도 이미 디폴트 파라미터를 정의하셔서 생략도 가능할 거 같습니다.
그리고 만약 초기값을 변수로 만들어서 사용하신다면 아래 60번째 줄, contentEditor.setState에서는 'document'로 변수를 전달하셨기 때문에 변수명이 서로 상이해서 통일하시는 게 좋을 거 같습니다! :))
await fetchPost(); | ||
} | ||
|
||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5) 마지막 리턴은 없어도 작동할 거 같아요!
@@ -0,0 +1,19 @@ | |||
const localStorage = window.localStorage; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p5) 아마 기능 추가를 하려고 만들다가 시간이 부족해서 못하신 것 같내요 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요 재현님! 코드리뷰하러 왔습니다 😉
코드가 예전보다 전반적으로 엄청 깔끔해 지신 것 같아요. 👍👍
좀 더 다양한 기능과 코드를 실험해보고 코드리뷰를 받아보는 것도 좋을 것 같습니다!
저도 이번에 작성하면서 엄청 여러지식도 늘고 되게 재밌었거든요 일단 만들어보니.. ㅋ.ㅋ
다른 팀에서도 파이팅 하세요 !! 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요 재현님, 코드리뷰를 처음이자 마지막으로 해드리네요 ㅎ.ㅎ
다른 분들이 다 말씀해주셔서 딱히 드릴 말씀이 없지만 마지막 리뷰 해드릴게요 : )
1달동안 수고하셨습니다~
if (this.state.documentId !== nextState.documentId) { | ||
this.state = nextState; | ||
|
||
if (this.state.documentId === "new") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.stat.documentId 중첩해서 나오는데
상수화 시켜서 사용하면 좀더 직관적으로 보일 듯 하네요 ㅎㅎ
}; | ||
|
||
this.render = () => { | ||
if (!this.state) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이부분은 굳이 없어도 될 것 같습니다 ㅎㅎ 아니면 따로 함수로 만들어서 관리하는 것도 좋겠네요 : )
|
||
push(`/`); | ||
|
||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return 없어도 될 것 같아요 ㅎㅎ
title: "", | ||
parent: id, | ||
}; | ||
const createdPost = await request("/documents", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"/documents" 상수화 하시면 좋을 것 같습니다 ㅎㅎ
@@ -0,0 +1,41 @@ | |||
.layout-main { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
css 모듈화 해보시는거 어떨까요? 폴더구조가 좀 더 직관적으로 보일 듯 합니다.ㅎㅎ
|
||
this.render(); | ||
|
||
$contentEditor.addEventListener("keyup", (e) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이벤트 리스너 함수로 묶어서 호출하는 방식으로
확장성에 대비해서 재사용하기 쉽게 관리하는 것도 괜찮아 보입니다. 그리고 함수로 묶으면 네이밍만 보고서도
코드를 읽는 입장에서 바로 알 수 있습니다. ㅎㅎ
@@ -0,0 +1,40 @@ | |||
import SideBar from "../components/SideBar/SideBar.js"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
App이 page 폴더에 있는건 살짝 투머치인것 같아요
디렉터리 구조 관련 링크 넣어둘게요~
아주 좋은 디렉터리 구조 관련 블로그글 여기 있네요!
이거는 tmi 유투브 링크입니다./
https://www.youtube.com/watch?v=UUga4-z7b6s
|
||
export default function SideBar({ $target }) { | ||
const $sideBar = document.createElement("div"); | ||
$sideBar.classList.add("layout-sidebar"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
classList.add 보다 className이 좀더 괜찮아 보이네요 ㅎㅎ
class="editor-content" | ||
name="content" | ||
> | ||
${this.state.content} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.state.content 말고 다른 대안으로
const {content} = this.state
이것도 괜찮아 보이네요 ㅎㅎ
this.setState(nextState); | ||
onEditing(this.state); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onEditing에서 nextState 바로 넘겨줘도 괜찮아 보이네요 ㅎㅎ
📌 과제 설명
👩💻 요구 사항과 구현 내용
✅ 피드백 반영사항
✅ PR 포인트 & 궁금한 점