배경지식!
01. 처음으로 API를 사용해보기 > 비동기로 처리하기 위해 promise / asnyc / await 사용
02. 이벤트 부여하는 것을 유틸에 모아다가 렌더링 후 부여하는 방식을 사용해봄
03. 검색 API가 있다는 것을 처음에는 몰라서 헤메다가 나중에 검색 API를 사용
04. 렌더링 테스트는.. 어떻게 하는 거죠..?
1번째 Push
설계 의도
* 컴포넌트는 본인의 템플릿과 이벤트를 가지고 있습니다.
* 컴포넌트 파일에서 이벤트를 부여하는 경우 렌더링이 이루어지지 않은 상태이기 때문에 이벤트 부여를 모아다가 렌더링이 끝난 이후 모은 이벤트를 부여해주었습니다.
* 처음에는 맨 상위 컴포넌트에서 랜더링을 해주었지만, 그런 경우 async가 상위 파일까지 타고 올라가버립니다. 때문에 API에서 오는 promise는 movie-list에서 렌더링을 해주었습니다.
* 위 사항을 따라 movie-list에서 렌더링을 해주다보니 movie-list 파일에서 렌더링 관련 함수(스켈레톤, 검색결과 보여주기, 인기영화 보여주기 등)를 가지고 있습니다.
* useMoive 파일은 api와 사용처 사이에서 징검다리 역할을 합니다. api에서 정보를 불러오기 위해 필요한 현재 검색상태 - 인기영화 상태 / 페이지 위치 등의 정보를 포함, 관리하고 있습니다. (이름을 바꾸고 싶었지만 시간이 없었습니다.)
* util은 이벤트 부여, 초기 렌더링 관련 함수를 담고 있습니다.
* 오류처리, 유효성 검사를 중요하게 생각하였으나 실제로 행하지는 못했습니다.
* 이전 미션에서 파일끼리 서로 임포트하는 상황이 있어 이번에는 관련성을 줄이고 파일의 역할을 명확하게 하고 싶었습니다.
* 이벤트 부여 위치, 시점이 늘 어려웠는데 이번에는 페어의 이전 경험을 적용해 새로운 방법을 시도해보았습니다.
리뷰
이 미션에서 어느부분이 도메인인지 잘 모르겠습니다. 처음에는 검색하는 것을 전체 API에서 필터링해야 한다고 생각해 이를 도메인이라고 생각했는데, 검색API가 있음을 알게되며 도메인이 사라졌습니다.
도메인이 명확하게 그려지지 않는다면 굳이 그 부분을 염두에 두고 작성할 필요는 없을 것 같습니다. 어떤 패턴이나 개념에 생각이 갇힌 채 코드를 작성하면 구현에 맞는 패턴이 아닌 패턴에 구현을 맞추게 될 가능성이 커 흐름이 부자연스러워질 수 있다고 생각해요. 코드는 어느정도 작성된 상태이니, 우선 상대적으로 명확한 레이어(컴포넌트, api, util 등)의 영역을 먼저 정리해두고 이외에 남는 로직들은 어떻게 정리할 것인지 고민해보면 어떨까 싶습니다. 이 작업 후에도 도메인이 딱히 필요하지 않겠다 싶으면, 그걸로도 충분할 것 같습니다.
리뷰 리뷰
> 도메인이 무엇일까 하는 고민은 1단계 내내 했던 것이다. UI와 domain을 분리하라는 미션에 아직까지도 잡혀있는 것 같다. 둘을 나누는 것이 중요하지만 콘솔게임에서 웹으로 넘어온 기점부터 도메인이 무엇인지 많이 어려워졌다. 지금 하는 미션은 대체로 데이터를 중심으로 UI에서 데이터를 받아 데이트를 추가하거나 혹은 조작에 대해 데이터를 수정하여 보여주거나 하는 것이 전부인 경우가 많았기 때문이다. 그래서 때때로 크루들과 도메인이 무엇인지에 대해 고민을 하곤 했는데 지금으로써는 위 위 말처럼 너무 도메인을 분리해야한다는 생각에 갇혀있기보단 필요에 의해 구조를 나누는 것이 맞는 것 같다.
2번째 Push
설계 의도
* movie-list 는 컴포넌트가 아니라고 생각을 하여 렌더링이 주된 역할인 showMovieList.ts로 변경하였습니다.
*showMovieList.ts와 api 사이에서 페이지 정보를 다루는 pageData.ts가 도메인에 가깝다고 생각하여 도메인으로 두었습니다.
다만, api와 긴밀히 연결이 되어있는데 도메인이라고 부를 수 있는 지에 대해서는 의문이 있습니다.
* 수정하며 제일 신경 쓴 부분은 동일한 작업(영화 리스트 렌더링)을 하는 경우 동일한 함수를 호출하도록 만들어 중복되는 코드를 제거하는 것이었습니다.
* 유틸 폴더 안 index.ts처럼 잡다한 함수가 한 파일에 모여있기도 하는데 이걸 다 따로 분리하는 것이 맞는지 모르겠습니다.
* 유틸 폴더 안에 있는 것들은 여러 파일에서 사용되거나 주요 로직이 아닌 서포트하는 기능만을 하는 경우에 유틸로 분류했습니다.
* 에러처리는 문제가 있는 경우 에러를 발생시키고 이것을 catch로 메인페이지 헤더에 띄워주는 방식으로 처리했습니다.
* 객체 내 속성으로 정보를 저장하는 방식에서 클래스로 수정 후 싱글톤 패턴을 이용했습니다.
리뷰
유틸 폴더 안 index.ts처럼 잡다한 함수가 한 파일에 모여있기도 하는데 이걸 다 따로 분리하는 것이 맞는지 모르겠습니다.
객체나 클래스를 관심사에 맞게 분리하듯이 파일 또한 관심사에 맞게 잘 관리되어야하는 부분이라고 생각합니다. 실제 현업에서 운용되는 프로젝트 같은 경우 utils로 취급되는 파일조차 몇 십, 몇 백개까지 존재하는데요, 현재 작성하시는 앱 규모에만 머물러있으시기보다는 이 프로젝트가 '대형 프로젝트가 된다면 어떤 식으로 코드와 파일들을 관리해야할까?'를 어느정도 고민하시면 좋을 것 같습니다.
다만, api오류처리가 처음이라서 오류처리가 부족하다고 생각합니다. 발생할 수 있는 여러 상황에 대해 말씀해주시면 더 고민해보도록 하겠습니다.
클라이언트 단에서 발생할 수 있는 에러 상황을 잘 다룬 아티클을 찾아보시면 좋을 것 같습니다.
네트워크 오류에서 네트워크 속도를 굉장히 낮게 설정하고 검색을 하고 연이어 바로 메인페이지로 가도록 클릭한다면 메인페이지로 헤더는 바뀌지만 목록은 처음 요청했던 검색어 결과를 노출합니다. 이런식으로 api를 가지고 오는 사이에 또다른 요청이 들어오는 경우 어떻게 방지할 수 있을지 모르겠습니다.
비동기 처리에 대하여 좋은 고민을 하신 것 같습니다. 이에 대한 힌트를 드리자면 web api로 제공하는 AbortController를 찾아보시면 좋을 것 같습니다.
showMovieList에서 showMovieList(callPlace, keyword)함수가 있습니다. 여기서 popular와 search 둘 다 대응하기 위해 keyword type을 string/null 로 설정하였습니다. null과 undefined 중 고민을 하였는데 어떤 것이 더 적절할까요??
null과 undefined의 차이와 쓰임새는 예전부터 자주 회자되던 주제이기도 합니다. 저는 명시적으로 비어있음을 나타내기 위해 null을 선호하나 이에 대한 차이는 먼저 찾아보신 뒤 본인의 기준을 만들어보시면 좋겠습니다.
리뷰 리뷰
> 리팩토링을 하며 막막했다. 어디서부터 손을 대야 하는 걸까 싶은 마음이 들었다. 이전에는 컴포넌트가 뭔지 몰라서 애먹었다면 이번에는 여기서 더 좋은 방향이 무엇인지 모르겠어서 손을 대지 못했다. 이전보다는 나은 것 같은데, 여기서 뭘 고쳐야 하는 걸까.. 그래서 일단은 그대로 가고 조금씩 필요하다는 것만 고쳐보았다.
아직까지 비동기에 익숙하지 않다는 느낌이 강하다. 그래서 그런지 손을 대면 틀어질 것 같다는 느낌이 강하게 드는데.. 우후후 어쩔 수 없다고 생각든다. 많이 해보는 수밖에..
네트워크 오류는 일단 생각나는 대로 했는데 다른 사람들 코드를 읽어보는 것이 좋을 것 같다.
1단계는 이렇게 마무리되었는데 마지막이라 그런지 조금 힘이 부친 미션이기도 했다. 2단계 역시 다양한 기능을 추가해야 하는데 걱정이 많이 된다. 조금씩 미션이 즐겁기보단 무서워지고 있는데.. 흉.. 그래도 많이 배우고 있는 기분이 들기는 한다.
'2022우아한형제들_우테코' 카테고리의 다른 글
[우테코] Lv. 2 다시뭐먹지 구현 (0) | 2023.05.03 |
---|---|
[우테코] Lv. 1 영화리뷰 구현 - 2단계 (0) | 2023.04.05 |
[우테코] Lv. 1 런치 구현 - 2단계 (0) | 2023.03.14 |
[우테코] Lv. 1 런치 구현 - 1단계(2차) (1) | 2023.03.14 |
[우테코] Lv. 1 런치 구현 - 1단계(1차) (0) | 2023.03.14 |