레벨2 페이먼츠 - step1
개요
미션 회고
리액트 온보딩 미션이 끝나고 두 번째 미션인 페이먼츠 미션이 시작되었다. 페이먼츠 미션은 총 3단계로 이루어져 있다. 지금까지는 2단계가 마지막이었는데, 3단계까지 있는 것을 보니 하나의 서비스에 대해서 더 많은 고민을 할 수 있게 될 것 같다.
페이먼츠 미션의 필수 요구 사항
은 다음과 같다.
Storybook으로 UI 컴포넌트 렌더링
REQUIREMENTS.md에 요구 사항 도출
재사용 가능한 Component 작성
📚 Storybook
새로운 키워드가 등장했다. 바로 Storybook
이다. Storybook은 UI 컴포넌트를 애플리케이션 외부에서 볼 수 있도록 도와주는 테스트 도구이다. 이는 왜 필요할까? 몇 가지 정리를 하자면 다음과 같다.
컴포넌트 주도 개발(CDD)을 할 때 유용하다.
만든 컴포넌트가 정상적으로 동작하는지 빠르게 확인할 수 있다.
배포를 할 수 있어 기획자, 디자니어와 소통할 수 있다.
이러한 장점을 느끼고자 1단계 미션은 Storybook를 활용한 CDD로 진행하였다. 초기 설정에서 버벅거림을 느끼고 배포하는 과정도 쉽지 않았지만 재밌는 경험을 하였다. 배포된 스토리북을 보면 다양한 상황의 컴포넌트를 확인할 수 있다. 확실히 규모가 큰 프로젝트인 경우 더욱 유용하게 사용될 것 같다는 느낌을 받았다.
여기서 story는 Jest에서 test와 같은 개념으로 생각하면 된다. 컴포넌트들이 가지고 있는 각각의 Story! 어떤 props를 전달받느냐에 따라 다양한 형태의 컴포넌트를 만들 수 있다. 즉, 다양한 이야기를 가지고 있는 컴포넌트라고 이해하면 좋을 것 같다. 이러한 컴포넌트들을 먼저 만들어 확인함으로써 CDD를 실천할 수 있다.
🧪 CDD from TDD
CDD(Component Driven Development)는 프론트엔드 진영의 개발 라이브러리들이 컴포넌트 형태로 개발하는 프로세스를 지향하고 있고, 웹 애플리케이션이 복잡해짐에 따라 등장한 개발 방법론이다. 컴포넌트들을 독립적으로 생가하고 하나의 동작 가능한 컴포넌트를 만드는 것을 시작으로 CDD를 적용할 수 있다.
지난 과거를 생각해보면 리액트를 이용해 페이지를 만들 때, 전체적인 페이지의 모습을 구상하는 것부터 시작하였다. 어떻게 보면 Top-Down 형식으로 코드를 작성했다.
하지만 앞으로는 다음과 같이 생각하고자 한다. 이는 CDD를 하기 위해 TDD을 적용한 것이다.
내가 무엇을 만들려고 하는가? - 큰 덩어리 생각하기
이를 위해 어떤 과정을 거쳐야 하는가? - 예외 상황을 포함하여 작은 덩어리로 쪼개기
그곳에서 가장 중요한 핵심은 무엇인가? - 가장 핵심이 되는 컴포넌트, 재사용이 용이한 컴포넌트 생각하기
위에서 생각한 컴포넌트가 실제로 어떤가? - 실제 사용되는 상황(엣지 케이스 포함) 생각하기
동작 가능한 컴포넌트를 만들고 UI 테스트 진행하기 - 테스트작성/컴포넌트구현
리팩터링 진행하기 - 위에서 작성한 테스트가 통과하는지 확인하기
1번 또는 2번으로 돌아가기
가장 까다로우면서 난해한 부분이 4번 과정이라고 생각한다. 작은 컴포넌트가 실제 서비스에서 어떻게 사용되는지를 파악하는 것이 그다음으로 해야 할 UI 테스트에 많은 영향을 주기 때문이다. 당연히 서비스가 확장되고 요구사항이 변할 수 있는 상황을 고려한다면 언제든지 컴포넌트의 기능이 조금씩 달라질 경우는 존재한다. 하지만 현재 고려할 수 있는 상황을 얼마나 생각하는 것이 실력 있는 개발자를 구별하는 것이지 않을까? 생각한다.
그래서 장점은...?
CDD를 적용함으로써 얻을 수 있는 장점은 다음과 같다.
재사용성
- 많은 곳에서 사용하는 컴포넌트를 먼저 생각하여 개발함으로써 재사용성을 높일 수 있다.유지보수
- 작은 작은 단위의 컴포넌트를 먼저 생각함으로써 의존성이 낮은 컴포넌트를 만들 수 있다.테스트
- 내가 원하는 UI 컴포넌트를 만들었는지 빠르게 테스트하고 피드백을 받을 수 있다.협업 효율성
- 기획자, 디자이너에게 컴포넌트에 대한 피드백을 자주 주고 받을 수 있다.(Storybook을 활용한다면 더욱)
dance of swtiching contexts
컴포넌트들이 춤을 춘다.
CDD를 적용하면 작은 단위의 컴포넌들이 실제 서비스에서 어떻게 움직이는지 자주 많이 확인한다. 이렇게 피드백을 자주 함으로써 컴포넌트들은 춤을 추게 된다고 한다. 즉, 컴포넌트들이 날뛰는(?) 상황이 된다면 비로소 CDD로 컴포넌트를 잘 개발하고 있다는 증거이다. 춤을 춘다는 표현이 적절하다고 하는데 아직 느끼기에는 많이 부족한가 보다.
내 컴포넌트들은 언제쯤 춤을 출까?
이번 페이먼츠 미션에서는...
이번 페이먼츠 미션에서는 다음과 같이 두 가지 컴포넌트에 대해서 CDD를 진행하였다.
CreditCard - 서비스에서
핵심
이 되는 컴포넌트, 앞으로 많은 페이지에서도재사용
되는 컴포넌트Input - 등록하는 기능에
핵심
이 되는 컴포넌트,반복
되는 컴포넌트
회고를 작성하는 현재 시점에서 추가했으면 하는 컴포넌트는 Button 컴포넌트가 될 것이다. 2단계에서는 조금 더 작은 단위로 생각할 수 있도록 연습하자.
🗺️ CRA에서의 Paths alias
그냥 paths alias가 아니라 CRA에서의 paths alias
이다. 이는 1단계에서 가장 많은 시간을 쓴 부분이다. 생각해 보면 필수 요구 사항도 아니고 당장은 심도 있게 다루지 않아도 되는 부분이긴 하지만 에러를 발견한 나로선... 그냥 넘어가기 싫었다.
paths alias를 적용하고 사용하는 방법과 CRA에서 paths alias를 적용할 때, 필요한 추가 설정은 따로 정리를 해두려 한다. 어찌됐든 이젠 다음처럼 절대 경로를 사용하여 파일을 import를 할 수 있다. deps가 많아지고 폴더가 많아질수록 더욱 유용하게 사용될 수 있을 것 같다.
🥸 가짜 input 보이기와 진짜 input 숨기기
신용카드 번호 16자를 입력하면 뒤 8자는 숨겨야 한다. 이를 구현하기 위해 4개의 input를 만들고 앞 두개는 number 또는 string 타입
으로 하고 나머지 두개는 password 타입
으로 하면 쉽게 해결할 수 있다. 하지만 나와 페어인 가브리엘은 하나의 input으로 만들고 싶었다. 당시에는 이미 뒤 8 자리를 숨기는 기능은 구현이 되어있었다. 때문에 화면에 보이는 것은 큰 무리가 없었다.
문제는 값을 저장할 때 발생한다. 8자리 이후 input에 새로운 값이 추가될 때 다음과 같은 순서로 진행된다.
input에서 현재 값을 가져온다.
현재 값 중 8자 이후의 값은 • 로 바꾼다.
위 과정을 통해 바뀐 값을 input의 value로 전달한다.
이러한 과정을 통해 8자리 이후의 값은 사라지게 된다. 즉, 저장을 할 때 1234123412341234가 아니라 1234••••••••가 저장이 되는 것이다. 이를 해결하기 위해선 원본을 다른 곳에 저장을 해야 한다.
이를 구현하기 위해 복잡하지만 하나의 input만 사용하는 방법으로 할지, 타이핑이 가능하지만 화면에 보여지지 않은 input(실제 값이 저장되는 input)과 화면에 보이는 용도로만 사용되는 또 다른 input을 만드는 방법으로 할지 가브리엘과 고민을 하였다.
개인적으로는 첫 번째 방법으로 도전하고 싶었지만 첫 번째 방법은 고려할 점이 많이 있었다. 중간에 번호를 추가 또는 삭제하는 경우, 여러개의 숫자를 한 번에 추가 또는 삭제하는 경우... 등등
때문에 일단은 완성이 목표이기 때문에 조금더 쉽고 직관적인 두 번째 방법으로 구현하였다.
아쉬운 점은 FakeInput에 커서가 없다는 점이다. 즉, 내가 현재 타이핑을 할 수 있나?라는 것을 사용자가 모를 수 있다는 것이다. 이를 일단은 css로 구현하였지만 완벽하지 않다. 이 점이 아쉬운 부분이다. 앞으로 step2, 3을 진행하면서 계속 고민을 해봐야겠다.
💬 Custom Hook인 useInput
1단계에서 useInput
훅을 만들었다. useInput
은 input의 유효성 검사도 함께 해주며 유효성 검사에 실패를 한다면 에러 메시지를 반환하는 역할도 한다. 때문에 input의 유효성 검사 함수를 배열로 넘겨줘야한다.
useInput의 코드는 다음과 같다.
에러 메시지가 없다면 그냥 useState만 사용해도 될 것이다. 하지만 모든 input에는 유효성 검사가 존재하고 실패할 경우 어떤 것 때문에 실패했는지를 사용자에게 알려줘야 한다. 이를 하나의 훅에서 관리를 하고 싶었다.
👬 페어프로그래밍 진행 과정
페이먼츠 미션의 페어는 가브리엘이다. 지난 페어프로그래밍에서도 페어와 함께 많은 이야기를 나누었는데, 이번 페어프로그래밍에서는 더 많은 이야기를 나누었다고 생각한다. 파일 구조, contextAPI, input, 컴포넌트 등등 같은 의견을 가지는 부분도 있었지만 서로 상반된 의견도 있었다. 서로의 의견을 말하고 하나로 합치는 과정이 잘 이루어져 만족스러운 페어프로그래밍이라고 생각한다.
첫째 날은 eslint와 storybook를 적용하느라 모든 시간을 사용했다. 참... eslint... 날 괴롭힌다. 분명 무언가를 놓치고 있는 것이 있을 텐데 빨리 익숙해졌으면 한다.(eslint에 대해 잘 알지 못하는 상태에서 적용만 하고 싶은 욕심이 더 크기 때문이지 않을까?)
아마 익숙해졌으면 첫날에 더 많은 것을 할 수 있었을 것이다. storybook도 처음 적용해 보았다. 잘 동작하는지 간단한 컴포넌트를 만들고 테스트도 진행하였다. 정상적으로 되니 가브리엘과 함께 즐거워했다.
둘째 날은 기능 구현에 속도를 높이고자 노력했다. CDD를 통해 먼저 CreditCard, Input 컴포넌트를 만들고 페이지를 만들기 시작했다. 전체적인 디자인, 기능은 순조롭게 진행되었다. 단, 위에서도 언급한 신용카드 뒤 8자리를 가리는 부분에서 의견이 엇갈렸고 어떻게 하면 좋을지 서로 고민을 하고 다음날 정하기로 했다.
셋째 날은 미션 제출일이기 때문에 완성에 목표를 두고 페어프로그래밍을 진행하였다. 전날 신용카드 번호에 대한 의견은 가브리엘의 의견에 따르기로 하였고 UI 측면에서 아쉬운 점은 있지만 어쨌든 앞으로 리팩터링을 통해 개선할 수 있으니 일단은 가짜 input를 만드는 방향으로 코드를 작성했다.
미션 제출 2시간 전, 페어 헤어지기를 하고 각자 부족한 부분을 채워나갔다. CVC 설명, 유효성 검사 부분이 미흡했기 때문에 제출 시간 전까지 해당 부분에 대한 코드를 작성하였고 배포까지 마무리하였다. PR메시지도 미리 작성해서 6시 전에 무사히 완료할 수 있었다.
👍 잘한 점
CDD를 적용하고자 노력했다.
작은 단위의 컴포넌트를 찾고자 노력했다.
페어와 대화를 정말 많이 나누었다.
👎 아쉬운 점
eslint 설정에 많은 시간을 사용했다.
시간 내에 미션을 완료하고자 했기 때문에 미흡한 부분이 많이 보인다.
👊 앞으로의 각오
eslint 설정에 대해 제대로 알아보자.
핵심이 되는 컴포넌트를 찾는 연습을 꾸준히 하자.
📅 2023-04-24
Last updated