[2단계 - 자주 가는 음식점] 수아(최수현) 미션 제출합니다.#81
Conversation
- 선호 여부 체크할 수 있는 이미지 등록 - 나중에 선호 여부 클릭 시 목록을 찾기 위해 레스토랑 객체에 id 항목 추가 - 선호 여부를 확인하기 위해 레스토랑 객체에 like 항목 추가
- 전체보기/ 선호 식당 보기 선택 섹션 구현
- 별 이미지를 선택하는 경우 선호가게 선택/해제되어 리스트 렌더링 수행
- 기존: 리스트를 인수로 받아 렌더링 - 수정: 인수없이 자체적으로 렌더링 구역이 모든 리스트인지, 선호 리스트인지 확인 후 렌더링
pocojang
left a comment
There was a problem hiding this comment.
2단계에 많은 노력을 하셨네요!
TDD 방법도 점점 구체적으로 진화하고 응용하시는게 많은 발전이 보입니다.
Q&A
컴포넌트 고민
컴포넌트에서 하는 일들을 빼내어 다른 곳에서 한다면 컴포넌트가 컴포넌트로 존재하는 것인지, 템플릿만 담은 파일인지 모르겠어서, 일단 반대로 각 컴포넌트에 함수를 넣었지만 파일간의 종속성이 강해지고 꼬여버리게 되어버렸습니다. 정답은 없다고 하지만 이 코드는 잘못된 것이 맞는 것 같습니다.. 구조에 대한 조언을 주시면.. 감사하겠습니다..
음 현재는 그림이 꼬여버리는거 아닌가요??!! 넘 걱정마세요
직접 그려보세요. 그래야 더 배우는 것도 많습니다!
저렇게 생성해주는 것은 보통 import, export 기반으로 그려서 엄청 꼬여서 그려주더라고요.
현재는 UI, 페이지 별로 나누고 공통 로직 같아보이는 것은 도메인으로 보내고 있는데요.
조언이라고 한다면.. 딱 2가지가 떠올라요.
App.js와 domain 계층입니다.
App.js에서 정말 많은 일을 하고 있는데 어디서 로직을 제어할 것인가에요.
현재 App.js는 마스터처럼 모든 것을 제어하도록 되어있어서 이 부분을 떼어내는 방향을 추천드리지만 아마 현재 앱이 커져서 어려우실거에요.
다음 미션에서 고민해보세요. App.js를 부모님이라고 생각하고 사사건건 모든 것을 통제하게 둘 것인가 vs 아니면 기본적인 틀만 주고 알아서 하도록 확장 시킬 것인가요 ㅎㅎ
domain 계층은.. 여전히 뭔가.. UI에 종속적인 느낌이라서 그 부분을 순수한 데이터 관점으로 드리븐해보시면 뭔가 해답이 보일 것 같네요
유효성 검사
유효하지 않은 값들이 들어오거나, select option index에 없는등 문제가 되는 상황에 대해 어떻게 대처할지 말씀해주셨습니다. 이미 html로 필수값 지정이 되어있거나 number 등으로 타입이 정해져 있는 경우에도 유효성 검사를 하는 것을 선호하시는 지 궁금합니다.
유효성 검사는 무조건 빡빡할수록 좋습니다
- [IT칼럼]'개발자 도구' 통한 결과도 서버의 책임
- 단순 조작에 뚫린 수능 성적표… "312명만 유출?"수험생 의심 증폭
- 2020 수능 성적표 미리 보기 가능? 인터넷 개발자 모드로 조작
유효성 검사 위치
어느 파일에서, 어느 부분에서 하는 것이 적절한지 궁금합니다. 이것 역시 try catch 등으로 다시 입력 받도록 유도하는 것이 좋을까요?
내 앱을 사용하는 사용자, 내가 만든 함수를 사용하는 동료 개발자 둘에게 어떻게 알려줄 것인가?!로 고민해보시는게 어떨까요!?
타입스크립트 사용에 대한 부분은 코멘트 리뷰드렸습니다 :)
또한 지금 시점에서 타입스크립트는 잘 못해도 되니까 너무 애쓰지는 마시고 뭘 공부하면 좋을지 내가 뭘 잘못하는지 정도만 캐치하거나 키워드만 기억하셔도 괜찮아요.
웹 그리고 JS와 친해지는 것만으로도 벅찰 수 있는 시기이고 실제로도 그게 더 중요합니다!
일단 Q&A만 답변 드리니 리뷰 반영 후 다시 요청해주세요!
README.md
Outdated
| # javascript-lunch | ||
|
|
||
| 우아한테크코스 레벨1 점심 뭐 먹지 미션 | ||
| 우아한테크코스 레벨2 점심 뭐 먹지 미션 |
| import { FilterSort } from "../src/domain/FilterSort"; | ||
| import { RestaurantData } from "../src/domain/RestaurantData"; | ||
|
|
||
| describe("필터/정렬이 적용된 레스토랑 리스트 만들기", () => { |
| cy.visit("http://localhost:8080/"); | ||
| }); | ||
|
|
||
| it("아무것도 선호 버튼을 누르지 않았을 경우 빈 목록", () => { |
There was a problem hiding this comment.
아무것도 선호 버튼을 누르지 않았을 경우 음.. 맥락 파악이 어렵군요?
| const [category, name, takeTime, description, link]: string[] = Array.from( | ||
| form.values() | ||
| ).map(String); |
| }, | ||
|
|
||
| getInfo() { | ||
| RestaurantData.id++; |
There was a problem hiding this comment.
RestaurantData.id++를 매번 증가시켜야하는 이유가 어떻게 될까요?
| if (elem.like) { | ||
| elem.like = false; | ||
| this.deleteLikeRestaurant(id); | ||
| } else { | ||
| elem.like = true; | ||
| this.addLikeRestaurant(id); | ||
| } |
There was a problem hiding this comment.
| if (elem.like) { | |
| elem.like = false; | |
| this.deleteLikeRestaurant(id); | |
| } else { | |
| elem.like = true; | |
| this.addLikeRestaurant(id); | |
| } | |
| if (elem.like) { | |
| this.deleteLikeRestaurant(id); | |
| } else { | |
| this.addLikeRestaurant(id); | |
| } | |
| elem.like = !elem.like; |
src/domain/RestaurantData.ts
Outdated
| return this.allList.filter((res) => { | ||
| return res.id === id && res; | ||
| })[0]; |
There was a problem hiding this comment.
음 조금 애매하긴한데 filter()가 아닌 find() 활용도 가능할지 확인해보세요 :)
| const target = event.target as HTMLElement; | ||
| const targetId = target?.closest("li")?.id; | ||
|
|
||
| // 잘못된 영역 클릭 시 방지 |
There was a problem hiding this comment.
closest, matches, outside 와 같이 대중적으로 사용되는 네이밍도 있답니다 :)
| </div>`; | ||
|
|
||
| return ` | ||
| <div> |
src/domain/FilterSort.ts
Outdated
| FilterSort.filterState = filter.options[filter.selectedIndex].value; | ||
| FilterSort.sortState = sortBy.options[sortBy.selectedIndex].value; |
There was a problem hiding this comment.
selectedIndex 검증까지는 아니더라도 없을때의 대응이 있으면 좋습니다 :)
- 기존: allList 배열의 길이로 초기값 설정. 이후 객체 생성 시 +1 처리. - 수정: allList가 없다면 0 , 있다면 마지막 요소의 id가 초기값. 이후 객체 생성 시 마지막 요소의 id확인
pocojang
left a comment
There was a problem hiding this comment.
Q&A
Q1.
id를 사용하는 것에서 문제가 발생할 수 있다고 해주셨는데, 저 역시도 지금처럼 보호받지 못하는 객체배열, id, class, index 등을 기준으로 로직을 짠다면 리팩토링을 하다가, 기능을 추가하다가 자칫 문제가 생길 수 있다고 생각됩니다. 데이터를 다른 곳에 백업을 해놓는 것이 안정성을 높일 수 있는 대안이 될지, 다른 방식이 있을지, 혹은 이를 보호할 함수가 있을지 궁금합니다.
id, class, index를 기반으로 셀렉터를 활용하고 코드를 작성하는 것이 무조건 문제라는건 아닙니다 ㅎㅎ
하지만 이것은 케이스에 따라 달라요 🤔
id, class는 브라우저에 수 많은 HTML 요소를 개발자가 DOM으로 가져와 어떻게 활용할까? 인것인데요 거기서 그 식별자들을 구별할때 예상될 수 있는 문제점이 보여서 말씀드려봤고요
index 같은 경우에도 언제나 순서가 일정할까? 이 데이터가 서버에서 오는거라면? 유저가 잘못된 정보를 넘긴다면? 이런 관점에서 코드를 작성해보시면 됩니다.
지금은 TDD도 열심히 공부하고 계시니 함수보다는 어떻게 꼼꼼하게 오류가 없는 코드를 만들 수 있는 개발자가 될까라는 의식적인 생각만 있어도 충분해요 💭
Q2.
"description 검사를 여기서 하면 되지 않을까요? "를 처리해보았는데 말씀하신 부분이 이렇게 처리하라는 말씀이신지 확인 부탁드립니다!
무조건 인라인으로 집어넣으라는 의미는 아니고요 ㅎㅎ
돔에 그려질때까지 불필요하게 2회의 조건을 조회하고 있어서 1회로 변경해보라는 이야기였답니다 😅
다음 미션을 위해 이만 놓아드리겠습니다 👋
화이팅!
말씀주신 부분 수정했습니다!
구조적인 부분을 수정하기엔 시간이 없어서 소소한 부분을 수정했습니다.
구조적인 부분, 유효성 검사, closest, matches, outside 와 같이 대중적으로 사용되는 네이밍, 타입추론 등은 더 생각해보도록 하겠습니다.
궁금한점
id를 사용하는 것에서 문제가 발생할 수 있다고 해주셨는데, 저 역시도 지금처럼 보호받지 못하는 객체배열, id, class, index 등을 기준으로 로직을 짠다면 리팩토링을 하다가, 기능을 추가하다가 자칫 문제가 생길 수 있다고 생각됩니다. 데이터를 다른 곳에 백업을 해놓는 것이 안정성을 높일 수 있는 대안이 될지, 다른 방식이 있을지, 혹은 이를 보호할 함수가 있을지 궁금합니다.
"description 검사를 여기서 하면 되지 않을까요? "를 처리해보았는데 말씀하신 부분이 이렇게 처리하라는 말씀이신지 확인 부탁드립니다!