Conversation
JunilHwang
left a comment
There was a problem hiding this comment.
점점 코드가 풍요로워지고 있군요 ㅎㅎ
좋습니다 👍👍👍
| export const frozen = (value) => { | ||
| let frozenValue; | ||
| if (Array.isArray(value)) { | ||
| frozenValue = []; | ||
| frozenArray(frozenValue, value); | ||
| } else if (typeof value === "object" && value !== null) { | ||
| frozenValue = {}; | ||
| frozenObject(frozenValue, value); | ||
| } else { | ||
| frozenValue = value; | ||
| } | ||
| return frozenValue; | ||
| }; | ||
|
|
||
| const frozenArray = (frozenValue, arr) => { | ||
| arr.forEach((v, i) => { | ||
| if (typeof v === "object" && v !== null) { | ||
| frozenValue[i] = frozen(v); | ||
| } else { | ||
| frozenValue[i] = v; | ||
| } | ||
| }); | ||
| }; | ||
|
|
||
| const frozenObject = (frozenValue, obj) => { | ||
| for (const [k, v] of Object.entries(obj)) { | ||
| if (typeof v === "object" && v !== null) { | ||
| frozenValue[k] = frozen(v); | ||
| } else { | ||
| frozenValue[k] = v; | ||
| } | ||
| } | ||
| }; |
There was a problem hiding this comment.
객체를 변경하지 못하게 만드는 함수가 아니라, 객체를 복사하는 함수 같아요!
그렇다면 frozen이 아니라 deepCopy 처럼 표현하면 어떨까요?
| case ADD_TODO: | ||
| return { ...state, todos: action.payload }; | ||
| case DELETE_TODO: | ||
| return { ...state, todos: action.payload }; | ||
| case TOGGLE_TODO: | ||
| return { ...state, todos: action.payload }; | ||
| case EDIT_TODO: | ||
| return { ...state, todos: action.payload }; |
| get state() { | ||
| return frozen({ ...this.#state }); | ||
| } | ||
| get props() { | ||
| return frozen({ ...this.#props }); | ||
| } |
There was a problem hiding this comment.
구조해제할당은 하지 않아도 똑같이 동작할 것 같아요 ㅋㅋ
| events.forEach((event) => { | ||
| this.#addEvent(event.type, event.target, event.handler); | ||
| }); |
There was a problem hiding this comment.
| events.forEach((event) => { | |
| this.#addEvent(event.type, event.target, event.handler); | |
| }); | |
| events.forEach(({ type, target, handler }) => this.#addEvent(type, target, handler)); |
사람마다 선호도의 차이가 있겠지만, 저는 이렇게 표현하는게 좋은 것 같아요! 더 깔끔한 느낌?
| const events = this.event(); | ||
| if (!events) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
| const events = this.event(); | |
| if (!events) { | |
| return; | |
| } | |
| const events = this.event() || []; |
이러면 한 방에 해결되지 않을까요!?
| for (const [key, value] of Object.entries(newState)) { | ||
| if (!state.hasOwnProperty(key)) continue; | ||
| state[key] = value; | ||
| } |
There was a problem hiding this comment.
이런 로직도 유틸함수로 만들어서 관리할 수 있겠네요!
|
|
||
| renderPath(); | ||
|
|
||
| window.addEventListener("locationChange", renderPath); |
There was a problem hiding this comment.
locationChange라는 이벤트 타입도 상수로 관리할 수 있지 않을까 싶어요~
| window.addEventListener("popstate", (e) => { | ||
| this.#setUrl(e.target.location.pathname); | ||
| }); |
There was a problem hiding this comment.
pathname만 가져다가 사용하게 되면 queryString이나 hash 같은건 무시되지 않을까요?
There was a problem hiding this comment.
https://developer.mozilla.org/ko/docs/Web/API/URL/URL
위의 API를 활용하면 조금 더 편리하게 router에 대한 정보를 관리할 수 있답니다!
| #parse(url) { | ||
| const splitUrl = url.split("?"); | ||
| const path = splitUrl[0]; | ||
| const queryString = {}; | ||
|
|
||
| if (splitUrl.length > 1) { | ||
| splitUrl[1].split("&").forEach((query) => { | ||
| const [key, value] = query.split("="); | ||
| if (key && value) { | ||
| queryString[key] = value; | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| return { path, queryString }; | ||
| } |
|
|
||
| const locationChange = new CustomEvent("locationChange"); | ||
|
|
||
| export default class HistoryRouter { |
🎯 완료한 Task
피드백
학습 시간
몰입
미션