-
Notifications
You must be signed in to change notification settings - Fork 89
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
[1단계 - 음식점 목록] - 버건디(전태헌) 미션 제출합니다. #104
Conversation
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com>
@@ -16,6 +16,6 @@ | |||
"strict": true, | |||
"skipLibCheck": true | |||
}, | |||
"include": ["src"], | |||
"include": ["src/**/*"], |
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.
공부해보아서 정리해본 바로는,
src는 바로 하위에 있는 경로에 파일들만 ts 컴파일 대상으로 포함하는 반면에,
저렇게 `/**/*` 를 포함해주면 src 안에 있는 모든 경로들이 ts 컴파일 내로 포함된다.
입니다! 혹시 제가 잘못 알고 있는점이 있거나 더 추가해서 알아야할점이 있다면 짚어주시면 감사하겠습니다!
src/types/components.d.ts
Outdated
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.
안녕하세요 블링 :) 한번 피드백 주신부분들 보완해서 올려보아요.
현재 공용 컴포넌트들에 대한 Props 타입들이 각각 컴포넌트들마다 선언해준 상태인데요 .
속성값들로 들어가는 id
, className
, name
, required
등 많은 부분들이 모든 태그에 다 들어갈수 있지 않을까 ?
라는 생각이 들어서 하나로 다 합쳐주고 받는 쪽에서 Partial<>로 받아주어야하나 고민을 했는데요
이러면 해당 컴포넌트에서 다 if 로 체크를 해주어야해서 함수 라인이 너무 길어지더라구요 🥲
그래서 현재 점심뭐먹지 미션에서 사용되는 속성들에 따라서 컴포넌트를 나누어주었는데 조금은 아쉽습니다.
공용 컴포넌트를 선언해주는거니까 일단 모든 속성들을 허용해주는게 맞는걸까요 ?
함수 10줄 라인 제한 조건때문에 본의 아니게 오버엔지니어링이 되는것 같다는 걱정도 드네요..!
모든 태그에 관한 공용 타입을 하나 선언해주고 그것을 컴포넌트마다 Partial로 받아서 if로 체크해주고 속성을 설정해주면 되는것 같은데 뭔가 억지로 일일히 나누어준거 아닌가? 라는 생각도 듭니다.
제가 아직 타입스크립트에 관한 능력이 부족해서인걸꺼요 ? 더 똑똑한 방법이 있을지 여쭤보고 싶어요!
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.
필요한 것을 빼고는 닫아두고, 필요에 따라서 하나씩 더 열어가는 방식도 협업 측면에서 필요할 수도 있다는 의견이긴 합니다.
협업의 관점에서는 한번도 생각해보지 못했던 부분이에요!
온전히 제가 불편함을 느껴서 말씀드린 부분인데, 더 넓은 인사이트 주셔서 감사합니다 :)
...DEFAULT_RESTAURANT_CATEGORY_UI_OPTIONS, | ||
]); | ||
|
||
export const MODAL_RESTAURANT_CATEGORY_UI_OPTIONS = Object.freeze([ |
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.
원래 렌더링 핸들러를 호출하는 곳에서 바로
Button({
className: TAG_CLASS_NAME,
text: TAG_TEXT,
type: TAG_TYPE,
});
으로 호출해주고 싶었는데, 이러면 함수가 10줄이 넘어가서 아예 컴포넌트를 반환해주는 유틸함수를 각각 컴포넌트마다 만들어 보았어요!
근데 이런 레이어 함수를 하나 더 두는것이 더 나은 방향성일지에 대해선 조금 의구심이 듭니다.
저는 함수 라인을 10줄로 제한한다는 조건은, 하나의 함수는 하나의 책임만 진다라는 의미에 기반해서 생겼다고 생각하는데요.
사실 저렇게 바로 컴포넌트를 생성해주는 함수에 옵션이 많아서 함수가 10줄이 넘어가기때문에 또 다른 함수를 만들어내는것 자체가 비용적으로 아쉽지 않나? 라는 생각도 들었습니다.
이에 대해서 블링의 의견도 한번 여쭤봐도 될까요 ?
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.
음.. 만약에 상수로 처리한 저 값들을 TAG_CLASS_NAME이 아니라 className이라면?
바로 Button(BUTTON_DATA) 식으로도 렌더링할 수 있으니 조금 더 나을까요?
조금 더 분량을 줄일 수 있는 방법은 더 고민해볼 수 있을듯 합니다.
그것과 별개로 버건디가 말씀해주신대로 10줄 제한의 의미가 무엇인지를 잘 생각해보고,
오히려 그것이 더 불편을 일으킨다면 과감한 선택을 내리는 것도 필요하다고 봅니다!
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.
말씀 감사합니다! 한번 고심해보도록 하겠습니다 🙇
}; | ||
|
||
export const renderDescriptionComponent = () => { | ||
const descriptionContainer = document.getElementsByClassName('description-container')[0]; |
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.
각각 모달에 있는 요소마다, 원래는 form-item
으로 공통으로 선언해주었었는데, 이러면 첫번째 formItem
요소 안에 모든 요소들이 appendChild
되는 문제가 발생했습니다..
이런식으로 margin-bottom이 각각의 form-item 클래스마다 적용이 되어야하는데, 하나의 form-item에 모든 요소가 들어가게 되더라구요.
그래서 불가피하게 각각 요소마다 클래스명을 따로 추가해주어서 각각 appendChild
를 해주었는데, 이러한 방식이 맞나? 라는 생각도 들었습니다.
각각 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.
저 이 질문을 잘 이해를 못했는데 혹시 관련된 코드 위치를 알려주시거나 예시를 써주실수 있을까요??
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.
설명이 부족했던점 죄송합니다!
원래는 Description
컴포넌트, Link
컴포넌트, InputName
컴포넌트 등 모달에 들어가는 form 엘리먼트 컴포넌트들이 전부
const formItem = document.getElementsByClassName('form-item')[0];
이라는 선택자를 받아서 해당 formItem
클래스에 appendChild를 해주었었습니다!
근데 기존 방식이었던, 아예 html 코드가 담긴 template
을 바로 돔으로 삽입해주었었을땐 괜찮았는데,
이제 공용 컴포넌트를 생성해서 바인딩 해주니, 각각의 formItem
컨테이너가 생성 되어서, 각각 요소가 분리 되는게 아니라
하나의 form-item
div에 전부 appendChild
가 되는 문제가 발생했어요! 즉, 각 요소마다 margin-bottom
속성이 먹혀야했는데,
전부 하나의 div로 들어가게 되니 댓글 사진 처럼 여백이 하나도 없는 문제가 발생했습니다.
그래서 이 문제를 해결하기 위해서 각각 form-item
클래스에 각 속성에 맞는 독립적인 클래스명을 추가해주었는데요!
각각의 div에 꽂아넣어주기 위해서 동일한 style 인데도, 별개의 클래스명을 생성해주는게 맞나 ?
라는 의구심이 들었어서 한번 여쭤보았습니다 :)
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.
아하 이건 아마도 자바스크립트의 문제인것 같은데요?
분명 조금 더 현명한 방법으로 form-item과 각 폼 요소들을 독립적으로 묶을 수 있는 방법이 있을 것 같아요!
@@ -0,0 +1,7 @@ | |||
const convertHTMLStringToDOM = (htmlString: string) => { | |||
const parser = new DOMParser(); |
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.
저번에 말씀주셨던 innerHTML
부분을 사용하지 않고 어떻게 DOM요소를 만들어줄수 있을까 알아보다가 DOMParser
에 대해서 알게 되었습니다!
그래서 문자열을 받아서, HTML 요소로 반환해주도록 함수를 변경해보았는데 이부분에 대해서 혹여나 잘못 짚고 있는 부분이 있다면 말씀주시면 감사하겠습니다 : )
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.
오호 DOMParser를 생각한 건 아니었지만 무언가 더 학습하셨다니 다행입니다!
innerHTML, DOMParser 모두 외부에서 주입하는 공격에는 취약한 부분이 있을 것 같은데요,
만약에 그냥 개발한 사람이 만든 것들을 렌더하는 것은 문제 없겠지만,
사용자가 만든 데이터를 기반으로 렌더링을 하는 과정에서는 이런 요소들이 보안적인 위협이 될 수도 있겠죠!
이런 측면에서도 한 번 고려해보고 탐구해봐도 좋을 것 같아서 언급해봅니다!
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.
2024-03-11.7.59.38.mov
지금은 이런것도 가능하거든요!
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.
2024-03-11.8.09.38.mov
이런것도!
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.
엄청나네요.. 🥲
한번 더 고민해보도록 하겠습니다! (이 부분은 지금 해결책이 잘 생각은 안나는데요..! 혹여나 수정이 안된다면 step2에서 까지 가져가면서 고심해보도록 하겠습니다..!)
짚어주셔서 감사합니다!
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.
지금 일단 아예 RestaurantListItem
이라는 개별의 리스트 아이템 컴포넌트를 만들어서 각각 document.createElement()
를 해주어서 블링이 영상 보내주신 상황은 막아놓은 상황입니다!
근데 제 페어같은 경우는 정규표현식으로 아예 값을 입력해줄때 그냥 태그를 제거해주는 방식으로 구현해보았는데요.
<h2>망가져라</h2>
라고 입력값이 들어가면 정규표현식을 통해서 망가져라
라고만 들어가도록 해주었더라구요.
str.replace(/<[^>]*>?/g, '');
저 같은 경우는 사실 아예 컴포넌트 별로 다 분리를 해주어서 공용 컴포넌트들을 만들어주었다는 것에 의의가 있지만, 그에 따른 시간비용이 좀 많이 들긴했는데요
페어가 구현한 방식은 시간이 많이 들지도 않고 문제가 됐던 상황도 예방해주는것 같다는 생각도 들었습니다!
혹시 이에 대한 블링의 의견 한번 여쭈어봐도 될까요?
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.
src/constants/error.ts
Outdated
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 를 하게 되었는데 불편 끼쳐드려서 죄송하다는 말씀 드립니다..!
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.
피드백 반영 전체적으로 많이 해주시느라 고생 많으셨습니다!
아직 좀 궁금한 점들이 많이 남아서 코멘트가 많은 편인데요,
이번 미션에서 다뤄보고 싶으신 부분들 위주로 먼저 보시고!
다음 단계에서 더 발전시켜보셔도 좋습니다.
그럼 조금만 더 화이팅입니다!
src/components/app/App.ts
Outdated
import RestaurantList from '../restaurant_list/RestaurantList'; | ||
|
||
function App() { | ||
const render = () => { |
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.
헉 놓친 부분이에요! 짚어주셔서 감사합니다 :)
if (name) textArea.name = name; | ||
if (id) textArea.id = id; | ||
if (rows) textArea.rows = rows; | ||
if (cols) textArea.cols = cols; | ||
if (className) textArea.className = className; |
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로 모든 것을 체크하는 것이 불편하다면, 기본값을 지정하는 방식으로도 해볼 수 있을 것 같은데 어떠신가요?
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.
파일명을 filter_bar/FilterBar.ts로 서로 다른 케이스로 구성하신 이유가 있나요??
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.
페어랑 작업하면서 서로 관성적으로 넘어갔던 부분인것 같습니다!
짚어주셔서 감사합니다 🙇 수정하겠습니다 !
import { Category, SortType } from '../../types'; | ||
import RestaurantList from '../restaurant_list/RestaurantList'; | ||
|
||
const categoryFilterHandler = (categoryFilter: HTMLElement) => { |
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.
함수의 역할이 조금 더 명확하고, 유연해서 재사용 가능하도록 만들려면 어떤 방법이 좋을지 생각해보는 것도 좋을 것 같습니다!
제가 아직 부족한지라 말씀하신 이 부분에 대해서 감이 잘 안오는 느낌입니다. 🥲
음식점 카테고리
셀렉트 change 이벤트와, 거리순 or 이름순
에 관한 셀렉트 change 이벤트 자체가 같은 change
이벤트이니 재사용 가능한 함수로 추상화 해보아라.
라는 말씀으로 이해를 했는데요!
혹시 블링이 말씀하신 부분에 대한 내용이 맞으실까요 ?
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.
아하 저는 차라리 외부 사용처에서 addEventListener를 해주고, handler는 말그대로 handling만 해도 좋지 않을까 하고 생각했습니다.
// 사용처
const a = document.querySelector('.a')
a.addEventListener('click', handleA)
// 정의
const handleA = () => {}
이렇게 되면 handleA도 다른 요소에도 사용할 수 있는 가능성이 생기니까요!
더불어서 핸들러 안에서 addEventListener도 하지 않을 수 있어서 오해도 줄일 수 있구요.
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.
아하 이해했습니다. 맞는 말씀이네요. 한번 step2에서 반영하도록 하겠습니다~! 짚어주셔서 감사해요!
import restaurantStateStore from '../../../store/RestaurantStateStore'; | ||
import removeHTMLElementByClassName from '../../../utils/removeHTMLElementByClassName'; | ||
|
||
export const linkEventHandler = (link: HTMLElement) => { |
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.
input 요소에 link라는 네이밍을 해주니까 실제 link 정보나 사용자가 입력한 link랑 구분이 어려운 부분이 있네요!
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,7 @@ | |||
const convertHTMLStringToDOM = (htmlString: string) => { | |||
const parser = new DOMParser(); |
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.
2024-03-11.7.59.38.mov
지금은 이런것도 가능하거든요!
@@ -0,0 +1,8 @@ | |||
const removeHTMLElementByClassName = (className: string) => { | |||
const errorMessageHTMLElement = document.getElementsByClassName(className)[0]; |
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.
removeElementByClassName인데 errorMessage인 것은 아직 어색한 것 같아요!
함수명에서 말해주듯이 변수명도 그냥 HTMLElement여야 하지 않을까요?
errorMessage 말고 다른 것을 지우는데에도 사용할수 있을테니까요!
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.
맞는 말씀이네요!
짚어주셔서 감사합니다 블링~!
}; | ||
|
||
export const renderDescriptionComponent = () => { | ||
const descriptionContainer = document.getElementsByClassName('description-container')[0]; |
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.
저 이 질문을 잘 이해를 못했는데 혹시 관련된 코드 위치를 알려주시거나 예시를 써주실수 있을까요??
Object.assign(document.createElement('select'), { | ||
id, | ||
name, | ||
className, | ||
required, | ||
}); |
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.
다른 곳에서와는 다르게 여기서는 assign을 통해서 속성을 추가해주고 있네요!
왜 이런 차이가 생겼나요??
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.
처음에 공용 컴포넌트들을 만들어줄때, Object.assign()을 해준것이 아니라 그냥 단순히
const span = document.createElement('span');
span.className = className!;
span.textContent = text;
이렇게 지정을 해주었었는데요..!
셀렉트는 셀렉트 태그와 그 안에 옵션 태그들을 따로 만들어주어야하다보니 Object.assign()을 선택했던것 같습니다.
근데 추가 push 후 생각해보니 다른 컴포넌트들도 Object.assign()을 해주어도 되지 않나? 라는 생각이 들더라구요..!
그래서 다른 컴포넌트들 또한 수정해주려고 합니다!
@@ -0,0 +1,7 @@ | |||
const convertHTMLStringToDOM = (htmlString: string) => { | |||
const parser = new DOMParser(); |
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.
2024-03-11.8.09.38.mov
이런것도!
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,7 @@ | |||
const convertHTMLStringToDOM = (htmlString: string) => { | |||
const parser = new DOMParser(); |
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.
지금 일단 아예 RestaurantListItem
이라는 개별의 리스트 아이템 컴포넌트를 만들어서 각각 document.createElement()
를 해주어서 블링이 영상 보내주신 상황은 막아놓은 상황입니다!
근데 제 페어같은 경우는 정규표현식으로 아예 값을 입력해줄때 그냥 태그를 제거해주는 방식으로 구현해보았는데요.
<h2>망가져라</h2>
라고 입력값이 들어가면 정규표현식을 통해서 망가져라
라고만 들어가도록 해주었더라구요.
str.replace(/<[^>]*>?/g, '');
저 같은 경우는 사실 아예 컴포넌트 별로 다 분리를 해주어서 공용 컴포넌트들을 만들어주었다는 것에 의의가 있지만, 그에 따른 시간비용이 좀 많이 들긴했는데요
페어가 구현한 방식은 시간이 많이 들지도 않고 문제가 됐던 상황도 예방해주는것 같다는 생각도 들었습니다!
혹시 이에 대한 블링의 의견 한번 여쭈어봐도 될까요?
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.
각각의 요소들을 다 컴포넌트화 해서 분리를 해주다보니, 파일들도 많아졌고 함수가 길어졌다는 생각이 드네요.. 🥲
그래도 바로 innerHTML에 꽂아 넣어주는 방식보다 나은 방법일까요..?
제가 생각했을때 현재 구현 방식에 대한 단점은
-
appendChild가 많아서 직접 DOM에 자주 접근을 하게 된다. (
fragment
를 새롭게 알게 되어서 이부분을 줄여주려고 해보았지만 여전히 많이 접근을 하게 되는것 같네요..!) -
각각 섹션들을 공용 컴포넌트들을 활용하여 만들어주다보니, 컴포넌트 데이터, 컴포넌트 만들어주는 유틸함수 등 딸려오는 부가 비용들이 많이 든다.
정도 인것 같습니다.
이러한 방식에 대한 블링의 의견 한번 여쭙고 싶습니다 :)
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.
이런 길을 가기로 한 이상 파일 수와 코드 양이 많아지는 것은 불가피하다고 보이긴 합니다.
다만 잘 정리해두고 통일성이 있다면 유사한 구조의 코드를 읽는 시간은 그렇게까지 많이 들지는 않을 것 같아요.
appendChild도 최대한 js에서 들고 있다가, 다 조합이 되면 큰 단위로 실제 DOM에 한번에 붙이는 방식으로 조금은 비용을 더 줄일 수 있지 않을까 생각합니다.
그 외에 다양하게 생기는 부산물들은 오히려 잘 분리되어서 수정하기도 용이하고 다른 곳에도 활용할 수도 있을 것 같아요.
어느정도는 정리와 반복 줄이기가 필요하겠지만 지금 방향이 틀린 방향이라고 생각하지는 않습니다!
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.
와 정말 수고하셨습니다!!
다양한 방면으로 탐구도 하셨고 의견도 나눈 것 같아서 기쁘네요.
지금 나눈 대화들을 토대로 2단계에서는 더 발전된 모습을 볼 수 있지 않을까 기대합니다!
아직 미해결인 부분들이 있지만, 저희가 1단계는 충분히 불태운 것 같아서 이만 여기서 머지하겠습니다!
2단계까지 화이팅입니다!! 🔥🔥🔥
import RestaurantList from "../../restaurant_list/RestaurantList"; | ||
|
||
const initializeFormState = () => { | ||
const modalForm = document.getElementById("modal-form") as HTMLFormElement; |
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.
-
말씀하신 getElementsBy~ 매서드들은 HTMLCollection을 반환해서 타입적으로 오류가 없었던 것이네요. 근데 이 때도 마찬가지로 찾지 못하면 빈 컬렉션(유사 배열)이 반환될 텐데, [0]에 접근해서 무언가 하려고 했을 때는 런타임 오류가 발생할 것 같아요. 지금처럼 modal-form이라는 id가 거의 무조건 있을 것이고 폼요소라는 것이 명확하면 단언을 해주는 것이 좋은 선택일 수도 있어보입니다!!
-
저는 되도록이면 id를 사용하는 것을 지양하는 편입니다. id가 고유하다는 것이 어차피 개발자가 지켜야할 룰이라면 className도 고유하게 만들어주면 되는 것 아닐까요? 요건 의견이 궁금합니다.
-
index로 불러오는 것도 위험한 선택입니다. DOM 구조는 언제든지 바꿀 수 있고 지금처럼 동적으로 요소들을 생성하고 제거하는 경우에는 더 그렇겠죠
-
querySelector를 사용하면 더 유연하게 DOM을 선택할 수 있게 됩니다. 예를 들면 이렇게 할 수 있겠죠
// 편의를 위해서 form에는 확실한 id가 있다고 하고
const submitButton = document.querySelector('#my-form .submitButton')
// 혹은
const form = document.querySelector('#my-form')
const submitButton = form.querySelector('.submitButton')
이런 부분들을 종합적으로 고민해보면 좋을 것 같네요!
}; | ||
|
||
export const renderDescriptionComponent = () => { | ||
const descriptionContainer = document.getElementsByClassName('description-container')[0]; |
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.
아하 이건 아마도 자바스크립트의 문제인것 같은데요?
분명 조금 더 현명한 방법으로 form-item과 각 폼 요소들을 독립적으로 묶을 수 있는 방법이 있을 것 같아요!
|
||
const RestaurantListStorageService = { | ||
getData() { | ||
const restaurantList = localStorage.getItem('restaurantList'); |
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.
class가 아니더라도 상태는 유지하도록 할 수 있을 것 같아요! 방법이 생각나지 않으신다면 closure를 찾아보셔도 좋구요!
그리고 기존 데이터와 새로운 데이터를 구분해서 받아야 할 필요성도 모르겠습니다.
외부에서는 이 데이터가 로컬스토리지의 데이터인지 캐싱해둔 데이터인지 알 필요 없이 항상 추가해둔 그대로만 받으면 되지 않을까요? 맨 처음에 캐싱 된 것이 없을 때만 캐시하도록 받아주면 되구요!
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,7 @@ | |||
const convertHTMLStringToDOM = (htmlString: string) => { | |||
const parser = new DOMParser(); |
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 (name) textArea.name = name; | ||
if (id) textArea.id = id; | ||
if (rows) textArea.rows = rows; | ||
if (cols) textArea.cols = cols; | ||
if (className) textArea.className = className; |
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.
음 사실 크게 상관은 없을 것 같은데, 신경이 쓰인다면 지금 상태로도 괜찮을 것 같네요!
import { Category, SortType } from '../../types'; | ||
import RestaurantList from '../restaurant_list/RestaurantList'; | ||
|
||
const categoryFilterHandler = (categoryFilter: HTMLElement) => { |
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.
아하 저는 차라리 외부 사용처에서 addEventListener를 해주고, handler는 말그대로 handling만 해도 좋지 않을까 하고 생각했습니다.
// 사용처
const a = document.querySelector('.a')
a.addEventListener('click', handleA)
// 정의
const handleA = () => {}
이렇게 되면 handleA도 다른 요소에도 사용할 수 있는 가능성이 생기니까요!
더불어서 핸들러 안에서 addEventListener도 하지 않을 수 있어서 오해도 줄일 수 있구요.
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.
이런 길을 가기로 한 이상 파일 수와 코드 양이 많아지는 것은 불가피하다고 보이긴 합니다.
다만 잘 정리해두고 통일성이 있다면 유사한 구조의 코드를 읽는 시간은 그렇게까지 많이 들지는 않을 것 같아요.
appendChild도 최대한 js에서 들고 있다가, 다 조합이 되면 큰 단위로 실제 DOM에 한번에 붙이는 방식으로 조금은 비용을 더 줄일 수 있지 않을까 생각합니다.
그 외에 다양하게 생기는 부산물들은 오히려 잘 분리되어서 수정하기도 용이하고 다른 곳에도 활용할 수도 있을 것 같아요.
어느정도는 정리와 반복 줄이기가 필요하겠지만 지금 방향이 틀린 방향이라고 생각하지는 않습니다!
* feat: setup build configurations and templates * docs: 기능 구현 목록 작성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * init: eslint setting Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 객체 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 리스트 도메인 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: index.js 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 파일 이름 오타 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: header 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: filter bar 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 리스트 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 도메인에서 로컬스토리지 사용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 사진 아이콘 import Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 컴포넌트 사진 임포트 및 컴포넌트 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 이벤트 리스너 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 오픈 이벤트 핸들러 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: dimmer 클릭시 모달 닫기 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 버튼 분리 및 카테고리 선택자 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: modal 내부 컴포넌트 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 탬플릿 변수 이름 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 데이터 store 및 필터링 서비스 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 카테고리 필터링 기능 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 문자열을 html dom 으로 변환하는 유틸 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 솔팅 메뉴 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 거리순 솔팅 중 같은 거리일 시 이름순으로 지정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 솔팅과 필터링 모두 적용 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 새로운 레스트랑 추가 기능 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 변경사항 이후리랜더 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 추가 모달 내부 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: filter bar 메서드 분리 및 format 함수 적용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: header 메서드 분리 및 format 함수 적용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: restaurant 컴포넌트 메서드 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: modal content format 함수 적용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: app 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: template 이름 변경 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 랜더 함수 호출 없애기 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 서브밋 버튼 클릭 후 validate 체크 및 에러 메세지 출력 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 에러 메세지 이후 수정시 메세지 삭제 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 핸들러 함수 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: css 클래스 이름 변경 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 서브밋 시 이전 에러 메세지 삭제 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 폼 제출/취소시 이전 데이터 삭제 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 등록된 가게 중복 체크 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 불필요한 메서드 병합 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: handler 분리 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: handler 분리 작업 및 불필요한 라인 정리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: eslint 세팅 후 리팩토링 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: mapped interface 사용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 파일 이름 변경 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: template 파일 이름 변경 후 import 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 랜더 핸들러 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 사용하지 않는 선언 삭제 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: package.json 불필요한 내용 삭제 * refactor: 문자열 DOM요소 변환 유틸함수 DOMParser API 사용으로 변경 * refactor: eventHandler 파일명 수정 및 함수명 변경 * feat: 공용으로 사용할 Select 컴포넌트 생성 * style: prettier 룰 추가 * style: prettier 룰 적용 * feat: 받은 옵션을 통해 공용 Select 컴포넌트를 만들어주는 함수 생성 * feat: 셀렉트 태그 관련 정보들 상수로 분리 후 바인딩 * refactor: 음식점 리스트 컴포넌트 초기화 함수 랩핑 삭제 * refactor: 헤더 컴포넌트 이벤트 핸들러 관련 파일명 수정 * refactor: eslint 룰 맞게 임포트 수정 * refactor: 컴포넌트마다 렌더함수 삭제 * feat: 공용 버튼 컴포넌트 생성 * feat: 버튼 관련 컴포넌트 데이터 생성 및 바인딩 * feat: 공용 Label 컴포넌트 생성 * refactor: 컴포넌트 생성 유틸함수 파일명 변경 * refactor: 공용 컴포넌트 타입 파일 분리 및 적용 * style: prettier 적용 * feat: 공용 Input 컴포넌트 생성 및 바인딩 * feat: 공용 Span 컴포넌트 생성 * feat: 링크 컴포넌트 공용 컴포넌트로 바인딩 * refactor: 공용 span 컴포넌트 생성 유틸함수 임포트 순서 변경 * feat: 음식점 이름 입력 컴포넌트 공용 컴포넌트로 바인딩 * refactor: 내부 변수명 변경 * style: 기존 파일 prettier 적용 * refactor: Select 공용 컴포넌트 required 속성 받도록 수정 * feat: 모달 내 카테고리 셀렉트 공용 컴포넌트 바인딩 * feat: 음식점 카테고리 데이터 상수 분리 * refactor: 기존 handlers였던 파일명 eventHandlers로 변경 * style: 기존 헤더 템플릿 prettier 적용 * refactor: handlers 파일명 eventHandlers로 변경 * feat: 공용 TextArea 컴포넌트 생성 및 바인딩 * refactor: 음식점 셀렉트 옵션 데이터 상수 분리 * feat: 거리 선택 셀렉트 공용 컴포넌트로 바인딩 * refactor: 기존 handlers.ts eventHandlers.ts 로 파일명 변경 * feat: description 컴포넌트 공용 컴포넌트로 바인딩 * refactor: eslint룰에 맞게 수정 * refactor: 독립된 ui를 위해 컨테이너 클래스명 추가 * refactor: 컴포넌트 옵션 데이터들 폴더별로 분리 * refactor: Helper 클래스 폴더 분리 * refactor : isValid 프로퍼티 success 로 변경 * refactor: 에러메세지 상수 분리 * refactor: eslint 룰 맞게 수정 * refactor: 공용 컴포넌트 생성 Object.assign으로 변경 * refactor: App 메인 컴포넌트에서 render 함수 삭제 * refactor: 공용 TextArea 컴포넌트 수정 * reafctor: 파일명 수정 * refactor: 컴포넌트 관련 데이터 폴더 위치 변경 * refactor: 유틸함수 수정 * refactor: 함수명 수정 * refactor: 파일명 변경 * feat: 공용 컨테이너, 리스트 컴포넌트 생성 * feat: 공용 헤딩 컴포넌트 생성 * feat: 공용 이미지 컴포넌트 생성 * feat: 공용 P 컴포넌트 생성 * feat: RestaurantListItem 컴포넌트 생성 및 바인딩 --------- Co-authored-by: woowapark <shinyoung.park@woowahan.com> Co-authored-by: Hyelim Choi <HyelimChoi01@gmail.com>
* feat: setup build configurations and templates * docs: 기능 구현 목록 작성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * init: eslint setting Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 객체 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 리스트 도메인 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: index.js 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 파일 이름 오타 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: header 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: filter bar 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 리스트 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 도메인에서 로컬스토리지 사용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 사진 아이콘 import Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 컴포넌트 사진 임포트 및 컴포넌트 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 이벤트 리스너 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 오픈 이벤트 핸들러 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: dimmer 클릭시 모달 닫기 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 버튼 분리 및 카테고리 선택자 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: modal 내부 컴포넌트 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 탬플릿 변수 이름 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 데이터 store 및 필터링 서비스 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 카테고리 필터링 기능 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 문자열을 html dom 으로 변환하는 유틸 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 솔팅 메뉴 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 거리순 솔팅 중 같은 거리일 시 이름순으로 지정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 솔팅과 필터링 모두 적용 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 새로운 레스트랑 추가 기능 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 변경사항 이후리랜더 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 추가 모달 내부 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: filter bar 메서드 분리 및 format 함수 적용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: header 메서드 분리 및 format 함수 적용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: restaurant 컴포넌트 메서드 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: modal content format 함수 적용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: app 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: template 이름 변경 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 랜더 함수 호출 없애기 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 서브밋 버튼 클릭 후 validate 체크 및 에러 메세지 출력 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 에러 메세지 이후 수정시 메세지 삭제 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 핸들러 함수 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: css 클래스 이름 변경 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 서브밋 시 이전 에러 메세지 삭제 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 폼 제출/취소시 이전 데이터 삭제 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 등록된 가게 중복 체크 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 불필요한 메서드 병합 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: handler 분리 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: handler 분리 작업 및 불필요한 라인 정리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: eslint 세팅 후 리팩토링 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: mapped interface 사용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 파일 이름 변경 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: template 파일 이름 변경 후 import 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 랜더 핸들러 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 사용하지 않는 선언 삭제 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: package.json 불필요한 내용 삭제 * refactor: 문자열 DOM요소 변환 유틸함수 DOMParser API 사용으로 변경 * refactor: eventHandler 파일명 수정 및 함수명 변경 * feat: 공용으로 사용할 Select 컴포넌트 생성 * style: prettier 룰 추가 * style: prettier 룰 적용 * feat: 받은 옵션을 통해 공용 Select 컴포넌트를 만들어주는 함수 생성 * feat: 셀렉트 태그 관련 정보들 상수로 분리 후 바인딩 * refactor: 음식점 리스트 컴포넌트 초기화 함수 랩핑 삭제 * refactor: 헤더 컴포넌트 이벤트 핸들러 관련 파일명 수정 * refactor: eslint 룰 맞게 임포트 수정 * refactor: 컴포넌트마다 렌더함수 삭제 * feat: 공용 버튼 컴포넌트 생성 * feat: 버튼 관련 컴포넌트 데이터 생성 및 바인딩 * feat: 공용 Label 컴포넌트 생성 * refactor: 컴포넌트 생성 유틸함수 파일명 변경 * refactor: 공용 컴포넌트 타입 파일 분리 및 적용 * style: prettier 적용 * feat: 공용 Input 컴포넌트 생성 및 바인딩 * feat: 공용 Span 컴포넌트 생성 * feat: 링크 컴포넌트 공용 컴포넌트로 바인딩 * refactor: 공용 span 컴포넌트 생성 유틸함수 임포트 순서 변경 * feat: 음식점 이름 입력 컴포넌트 공용 컴포넌트로 바인딩 * refactor: 내부 변수명 변경 * style: 기존 파일 prettier 적용 * refactor: Select 공용 컴포넌트 required 속성 받도록 수정 * feat: 모달 내 카테고리 셀렉트 공용 컴포넌트 바인딩 * feat: 음식점 카테고리 데이터 상수 분리 * refactor: 기존 handlers였던 파일명 eventHandlers로 변경 * style: 기존 헤더 템플릿 prettier 적용 * refactor: handlers 파일명 eventHandlers로 변경 * feat: 공용 TextArea 컴포넌트 생성 및 바인딩 * refactor: 음식점 셀렉트 옵션 데이터 상수 분리 * feat: 거리 선택 셀렉트 공용 컴포넌트로 바인딩 * refactor: 기존 handlers.ts eventHandlers.ts 로 파일명 변경 * feat: description 컴포넌트 공용 컴포넌트로 바인딩 * refactor: eslint룰에 맞게 수정 * refactor: 독립된 ui를 위해 컨테이너 클래스명 추가 * refactor: 컴포넌트 옵션 데이터들 폴더별로 분리 * refactor: Helper 클래스 폴더 분리 * refactor : isValid 프로퍼티 success 로 변경 * refactor: 에러메세지 상수 분리 * refactor: eslint 룰 맞게 수정 * refactor: 공용 컴포넌트 생성 Object.assign으로 변경 * refactor: App 메인 컴포넌트에서 render 함수 삭제 * refactor: 공용 TextArea 컴포넌트 수정 * reafctor: 파일명 수정 * refactor: 컴포넌트 관련 데이터 폴더 위치 변경 * refactor: 유틸함수 수정 * refactor: 함수명 수정 * refactor: 파일명 변경 * feat: 공용 컨테이너, 리스트 컴포넌트 생성 * feat: 공용 헤딩 컴포넌트 생성 * feat: 공용 이미지 컴포넌트 생성 * feat: 공용 P 컴포넌트 생성 * feat: RestaurantListItem 컴포넌트 생성 및 바인딩 * feat: 탭 컴포넌트 구현 * refactor: 클로저를 활용하여 로컬스토리지 값 캐싱 * refactor: 음식점 목록 컴포넌트 외부에서 값 주입 받는 방식으로 변경 * refactor: restaurantList map 함수로 변경 * feat: 즐겨찾기 아이콘 컴포넌트 추가 및 데이터 프로퍼티 추가 * feat: 즐겨찾기 버튼 토글 버튼 기능 추가 * refactor: 헤더 컴포넌트 공용 컴포넌트 렌더링 방식으로 교체 * feat: 공용 Form 컴포넌트 생성 * refactor: 모달 컴포넌트 컨텐츠 외부 주입 받는 방식으로 변경 * feat: 공용 A태그 컴포넌트 생성 * feat: 음식점 리스트 태그 클릭시 상세모달 렌더링 * refactor: 모달 초기화 수정 및 컴포넌트 생성 파일 폴더로 분리 * feat: 상세모달 함수 바인딩 * feat: 상세모달에서 좋아요 토글 기능 메인창과 동기화 * refactor: 좋아요 버튼 관련 리팩토링 * feat: 바텀시트내에서 버튼 컴포넌트 구현 * feat: 공용 Main, Section 태그 컴포넌트 생성 * refactor: 필터바 공용 컴포넌트로 구성방식 변경 후 바인딩 * refactor: 카테고리 필터 관련 이벤트 재바인딩 * fix: 이벤트 버블링 오류 수정 * feat: 공용 Ul 태그 생성 * feat: ul컨테이너 작성 및 바텀시트 컴포넌트 생성 * refactor: 모달 관련 이벤트 리팩토링 * refactor: 바텀시트 스타일링 및 리팩 * chore : cypress 테스트를 위한 tsconfig.json 설정 * chore : cypress 셋팅 * test: cypress 테스트 코드 작성 * chore: eslint 수정 * chore : package-lock.json * refactor: 코드 10줄 넘는 함수들 분리 * test: 테스트코드 추가 작성 * feat: setup build configurations and templates * feat: 탭 컴포넌트 구현 * feat: 즐겨찾기 버튼 토글 버튼 기능 추가 * feat: 바텀시트내에서 버튼 컴포넌트 구현 * refactor: 모달 관련 이벤트 리팩토링 * refactor: 바텀시트 스타일링 및 리팩 * refactor: repush * refactor: repush * [1단계 - 음식점 목록] - 버건디(전태헌) 미션 제출합니다. (#104) * feat: setup build configurations and templates * docs: 기능 구현 목록 작성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * init: eslint setting Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 객체 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 리스트 도메인 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: index.js 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 파일 이름 오타 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: header 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: filter bar 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 리스트 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 도메인에서 로컬스토리지 사용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 사진 아이콘 import Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 컴포넌트 사진 임포트 및 컴포넌트 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 이벤트 리스너 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 오픈 이벤트 핸들러 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: dimmer 클릭시 모달 닫기 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 모달 버튼 분리 및 카테고리 선택자 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: modal 내부 컴포넌트 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 탬플릿 변수 이름 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 데이터 store 및 필터링 서비스 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 카테고리 필터링 기능 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 문자열을 html dom 으로 변환하는 유틸 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 솔팅 메뉴 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 거리순 솔팅 중 같은 거리일 시 이름순으로 지정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 솔팅과 필터링 모두 적용 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 새로운 레스트랑 추가 기능 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 변경사항 이후리랜더 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 레스토랑 추가 모달 내부 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: filter bar 메서드 분리 및 format 함수 적용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: header 메서드 분리 및 format 함수 적용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: restaurant 컴포넌트 메서드 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: modal content format 함수 적용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: app 컴포넌트 생성 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: template 이름 변경 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 랜더 함수 호출 없애기 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 서브밋 버튼 클릭 후 validate 체크 및 에러 메세지 출력 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 에러 메세지 이후 수정시 메세지 삭제 기능 추가 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 핸들러 함수 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: css 클래스 이름 변경 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 서브밋 시 이전 에러 메세지 삭제 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 폼 제출/취소시 이전 데이터 삭제 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * feat: 등록된 가게 중복 체크 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 불필요한 메서드 병합 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: handler 분리 작업 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: handler 분리 작업 및 불필요한 라인 정리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: eslint 세팅 후 리팩토링 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: mapped interface 사용 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 파일 이름 변경 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: template 파일 이름 변경 후 import 수정 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * refactor: 랜더 핸들러 분리 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: 사용하지 않는 선언 삭제 Co-Authored-By: JEON TAEHEON <109535991+brgndyy@users.noreply.github.com> * chore: package.json 불필요한 내용 삭제 * refactor: 문자열 DOM요소 변환 유틸함수 DOMParser API 사용으로 변경 * refactor: eventHandler 파일명 수정 및 함수명 변경 * feat: 공용으로 사용할 Select 컴포넌트 생성 * style: prettier 룰 추가 * style: prettier 룰 적용 * feat: 받은 옵션을 통해 공용 Select 컴포넌트를 만들어주는 함수 생성 * feat: 셀렉트 태그 관련 정보들 상수로 분리 후 바인딩 * refactor: 음식점 리스트 컴포넌트 초기화 함수 랩핑 삭제 * refactor: 헤더 컴포넌트 이벤트 핸들러 관련 파일명 수정 * refactor: eslint 룰 맞게 임포트 수정 * refactor: 컴포넌트마다 렌더함수 삭제 * feat: 공용 버튼 컴포넌트 생성 * feat: 버튼 관련 컴포넌트 데이터 생성 및 바인딩 * feat: 공용 Label 컴포넌트 생성 * refactor: 컴포넌트 생성 유틸함수 파일명 변경 * refactor: 공용 컴포넌트 타입 파일 분리 및 적용 * style: prettier 적용 * feat: 공용 Input 컴포넌트 생성 및 바인딩 * feat: 공용 Span 컴포넌트 생성 * feat: 링크 컴포넌트 공용 컴포넌트로 바인딩 * refactor: 공용 span 컴포넌트 생성 유틸함수 임포트 순서 변경 * feat: 음식점 이름 입력 컴포넌트 공용 컴포넌트로 바인딩 * refactor: 내부 변수명 변경 * style: 기존 파일 prettier 적용 * refactor: Select 공용 컴포넌트 required 속성 받도록 수정 * feat: 모달 내 카테고리 셀렉트 공용 컴포넌트 바인딩 * feat: 음식점 카테고리 데이터 상수 분리 * refactor: 기존 handlers였던 파일명 eventHandlers로 변경 * style: 기존 헤더 템플릿 prettier 적용 * refactor: handlers 파일명 eventHandlers로 변경 * feat: 공용 TextArea 컴포넌트 생성 및 바인딩 * refactor: 음식점 셀렉트 옵션 데이터 상수 분리 * feat: 거리 선택 셀렉트 공용 컴포넌트로 바인딩 * refactor: 기존 handlers.ts eventHandlers.ts 로 파일명 변경 * feat: description 컴포넌트 공용 컴포넌트로 바인딩 * refactor: eslint룰에 맞게 수정 * refactor: 독립된 ui를 위해 컨테이너 클래스명 추가 * refactor: 컴포넌트 옵션 데이터들 폴더별로 분리 * refactor: Helper 클래스 폴더 분리 * refactor : isValid 프로퍼티 success 로 변경 * refactor: 에러메세지 상수 분리 * refactor: eslint 룰 맞게 수정 * refactor: 공용 컴포넌트 생성 Object.assign으로 변경 * refactor: App 메인 컴포넌트에서 render 함수 삭제 * refactor: 공용 TextArea 컴포넌트 수정 * reafctor: 파일명 수정 * refactor: 컴포넌트 관련 데이터 폴더 위치 변경 * refactor: 유틸함수 수정 * refactor: 함수명 수정 * refactor: 파일명 변경 * feat: 공용 컨테이너, 리스트 컴포넌트 생성 * feat: 공용 헤딩 컴포넌트 생성 * feat: 공용 이미지 컴포넌트 생성 * feat: 공용 P 컴포넌트 생성 * feat: RestaurantListItem 컴포넌트 생성 및 바인딩 --------- Co-authored-by: woowapark <shinyoung.park@woowahan.com> Co-authored-by: Hyelim Choi <HyelimChoi01@gmail.com> * fix: conflict로 인해 안올라갔던 파일들 재업로드 * chore: .gitignore에 DS파일 추가 * refactor: 테스트 코드 수정 * refactor: ATag => A로 변경 * refactor: 렌더 함수 분리 * refactor: as 선언 줄이기 * refactor: as 단언 if로 교체 * feat: filter sort 필터 관련 서비스레이어 생성 * refactor: filter, sort서비스 레이어 바인딩 * refactor: 타입가드 유틸함수 생성 후 바인딩 * refactor: 주석삭제 * refactor: 이벤트 핸들러 로직 세분화 * refactor: 컴포넌트 데이터 각 항목별 한 파일로 병합 * refactor: 파일 한곳에서 가져오기 * chore: eslint 룰 변경 * feat: localStorage 객체 생성 * feat: 로컬 스토리지 핸들러 생성 * refactor: RestaurantStorageService를 로컬스토리지로 변경 * refactor: 유틸함수 한줄로 분리 * feat: 스토리지 서비스 분리 --------- Co-authored-by: woowapark <shinyoung.park@woowahan.com> Co-authored-by: Hyelim Choi <HyelimChoi01@gmail.com>
배포링크
안녕하세요 블링 ! 만나서 반갑습니다. 처음 뵙겠습니다 버건디라고 합니다 :)
저와 페어는 이번에 웹 컴포넌트가 아닌 일반 함수로 컴포넌트들을 분리해서 코드를 작성해보았는데요.
웹 컴포넌트를 사용하지않아야겠다 라고 판단한 근거는 이렇습니다.
1. 웹 컴포넌트의 장점이라고 할수 있는 스타일 격리가 그렇게 큰 장점이 되지 않을수도 있다.
웹 컴포넌트의 장점 중 하나는, 쉐도우 돔을 통해서 내부 컴포넌트의 스타일을 격리할수 있는 것이라고 알고 있습니다!
하지만 이러한 스타일 격리는,
component.module.css
같은 컴포넌트별에 해당하는 module css파일로도 충분히 컴포넌트별로 독립된 스타일을 보장 해줄수 있지 않나? 라는 생각이 들었어서 크게 장점이라고 생각되지는 않았습니다.(이번 미션에서는 일단 기본 템플릿으로 내장 되어있던 style.css를 사용하였는데, step2에서 module css로 분리해보겠습니다 🙇)
2. 높은 종속성
웹 컴포넌트는 쉐도우 돔을 통해서 스타일 격리 뿐 아니라, 스크립트 격리도 해주는 것으로 알고 있는데요.
하지만 각 컴포넌트 별로 이벤트 핸들링 후의 값들을 주고 받으려면
CustomEvent
객체를 통해서 결국 외부로 전파를 해주어야했습니다.이는 단순히 컴포넌트 내부의 이벤트 핸들러 뿐만 아니라, 실제 돔으로 상태 값을 전달하기 위한
dispatch
함수가 또 필요하다고 생각했습니다.이러한 부분들은 높은 독립성을 보장해주지만, 반면에 높은 종속성 또한 겪을수밖에 없다라고 생각했습니다.
웹 컴포넌트 공부하면서 만들어본 기본 컴포넌트의 구조인데, 사용하고 싶은 컴포넌트마다 해당 컴포넌트를
extends
를 통해 상속 받아야지만 이벤트 핸들링과 dispatch를 사용해줄수 있다보니 이 자체가 강한 종속성을 만들어준다고 생각했습니다 !3. 쉐도우DOM과 스크립트 격리를 통한 리소스 소모
실제 돔에서 컴포넌트 별로 나누어서 핸들링 할때 걱정되고 고민 됐던 부분은 실제 DOM에 접근하다보니 비용적으로 웹 컴포넌트보다는 더 비용이 크게 들지 않을까? 라는 점이었는데요.
하지만 웹 컴포넌트도 shadow dom을 조작하기 위한 비용이나 shadow dom을 넘어서 실제 dom에 이벤트를 전파하기 위한 비용, 그리고 전파 후에 결국엔 실제 dom을 조작해야하는 비용 등을 감안했을때, 성능상 이 두개의 큰 차이는 없지 않을까 ? 라고 판단했습니다. (실제 수치화를 해보지는 않아서 온전히 주관적인 판단인 점 양해 부탁드립니다! )
즉, 웹 컴포넌트의 장점이라고 뽑히는 부분들이 저에게 "웹 컴포넌트를 통해 이번 미션을 해결해야겠다!" 라는 공감까지 이끌어내지는 못했던것 같습니다.
혹시 제가 위에 기재한 이유들에 대해서 블링은 어떻게 생각하실지, 혹여나 제가 잘못 짚고 있는 점이 있다면 말씀 주신다면 감사하겠습니다! 🙇
또한 이번에 저희는 컴포넌트별 랜더링을 진행할때 함수를 사용해서 리액트의 함수형 컴포넌트의 느낌을 내려고 해보았는데요.
하지만 이도 결국 직접 DOM에 렌더링을 하게 되는 방식이라서 사실 많이 어설프기도 한것 같습니다.
혹시 저희가 구현한 방식에서 더 보완해볼 부분이나, 잘못 짚고 있는점이 있다면 말씀주시면 감사하겠습니다!
나머지 궁금증들 같은 경우 코멘트에 따로 남겨보겠습니다~!