[우테코] 페이먼츠 미션 - 2단계 정리

Sally·2022년 5월 9일
1

2단계 회고

페이먼츠 2단계에서는 Context API를 활용하여 상태관리를 하는 것이 주요 목표였다.

1단계에서 prop drilling의 번거로움과 귀찮음을 알았기 때문에 Context API를 활용했을 때 prop drilling이 얼마나 해결 될 것인지 약간의 기대감을 가지고 2단계 미션을 시작할 수 있었다.

추가적으로 Storybook의 상호작용 테스트를 추가적으로 진행하였는데, 솔직히 왜 하는지 하면서 감이 잘 잡히지 않았다. 1단계에서 컴포넌트 단위로 UI를 먼저 구현하였을 때에는 편리함과 장점을 많이 느꼈었다. 하지만 2단계에서 상호작용 테스트를 위해서 컴포넌트에 testid를 직접 부여하고 일일히 해당 값들의 예시 값들을 채워 넣는 과정이 번잡스럽기만 했다.

왜 이렇게 생각하게 됐는지 혼자서 지레 짐작을 해보자면, 아마 현재는 팀 단위로 개발을 하는 것이 아니라 이렇게 느끼는 것이 아닐까 생각이 들었다.

현재 단계에서 스토리북 상호작용테스트를 하는 것이 테스트 결과를 보는 사람도 나고 테스트 결과를 만들어 내는 것도 나였기에 필요를 못느꼈지만, 대규모의 협업으로 다른 사람들의 코드 결과물을 미리 볼때에는 유용하지 않을까?🧐 라는 생각만을 할 뿐이다.

Context API

이번 미션의 경우에는 페이지가 3가지로 이루어져 있다.

카드 입력 폼이 있는 AddCardPage, 카드 입력 폼에서 입력된 정보들을 토대로 이미지를 보여주는 카드 닉네임을 입력하는 AddCardResultPage, 입력된 카드 목록들을 보여주는 CardListPage가 있었다.

해당 3가지의 Page에서 공통적으로 필요한 데이터들은 카드 번호, 유저 이름, 유효기간 이였다.
(AddCardReulstPage와 CardListPage의 카드 이미지에서 해당 정보들을 보여주어야 했기 때문이다)

그리고 카드 목록으로 보여주어야 했기 때문에 새롭게 입력되는 카드 마다 객체로 값을 가공하여 배열에 넣어서 카드 목록 페이지에서 접근이 가능해야 했다.

해당 과정에서 어떤 것 까지 Context API로 관리를 해야하는지 고민이 되었다 🤔🤔🤔

기존의 1단계에서 관리한 state를 모두 Context API로 관리하기 위해서 App(최상단 컴포넌트)에서 다시 선언해서 하기에는 오히려 더 코드가 복잡해질 것 같았다.
(-> 하지만 나중에 깨달았다... Context 폴더로 분리해서 관리하면 될 것을...🥲)

그리고 모든 값을 Context를 관리하게 되면 상태가 변경되지 않은 곳까지 불필요한 렌더링이 발생할 것 같아 ContextAPI 사용을 조금은 줄이게 되었다.

<CardListContext.Provider value={{ cardList, setCardList }}>
    <Routes>
       <Route path="/react-payments/" element={<AddCardPage />} />
       <Route path="/react-payments/result" element={<AddCardResultPage />} />
       <Route path="/react-payments/list" element={<CardListPage />} />
    </Routes>
</CardListContext.Provider>

최종적으로 Context API로 관리하는 값은 CardList이다.

step1에서 구현한 ( props drilling이 구현된😅 ) AddCardPage의 코드는 그대로 두고,
카드 입력 폼에서 다음 (=submit 버튼)을 눌렀을 때에 Context API에 입력 폼에 입력된 값들을
객체 형태로 CardList에 push 해주었다.

그리고 카드 닉네임을 입력하는 페이지(=AddCardResultPage)에서 CardList의 마지막 요소에 접근하여 카드 이미지를 그려주고 닉네임을 입력하고 완료 버튼을 눌렀을 때에
객체에 닉네임 값을 업데이트 해주었다.

카드 리스트에서는 CardList 전체를 map을 통해서 Card컴포넌트로 전체 카드 리스트를 보여주었다.

이런식으로 구현하게 되니, 확실히 prop으로 구현할 부분이 많이 줄어서 카드 닉네임 입력 페이지와 카드 리스트 페이지 컴포넌트들을 구현할때의 코드가 간결해졌다.
그런데 이 부분이 카드 닉네임 입력 페이지와 카드 리스트의 컴포넌트가 구현할 양이 적어서 인지, Context API를 사용해서 인지 스스로도 아직 의문을 가지고 있다.😣

제어 비제어 컴포넌트

해당 키워드도 이번 미션에서 중요한 키워드였다.

사실, 비제어 컴포넌트를 왜 사용해야하는지 의문을 가지고 있었다. 제어 컴포넌트만으로도 기능이 잘 구현이 되고 있었기 때문에 굳이 복잡하게 ref를 일일이 붙여 가면서 비제어 컴포넌트를 구현해야할까? 라는 생각이 들었다.

결론적으로는 비제어 컴포넌트는 auto focusing를 구현하는 데에서만 사용이 되었다.

뭐, 리액트 공식 문서에서도 Ref를 사용해야할 때의 예시에
포커스, 텍스트 선택영역, 혹은 미디어의 재생을 관리할 때가 있었기에 해당 부분에서 사용하면 된거지 라는 생각도 들었다. 😅

그럼에도 아직까지 비제어 컴포넌트를 왜 사용해야 하는지 의문이 존재해서

주변 비제어컴포넌트를 사용해본 크루들에게 이유를 물어보았다.

설명을 듣고 나니 비제어 컴포넌트도 context API와 같이 사용하였을 때에 쓸모가 있어보였다.
예를 들어 닉네임의 입력칸이 있을 때에 제어 컴포넌트의 경우 한 글자 글자를 입력할 때 마다 상태가 변경되기 때문에 재랜더링이 발생한다. 하지만 ref를 활용해서 비제어컴포넌트로 구현하였을 때에는 제출 버튼을 눌렀을 때에 닉네임 값에 접근하기 때문에 불필요한 재랜더링을 줄일 수 있다.

이렇게 예시를 통해서 설명을 듣고나니, ref를 좀 더 사용해볼껄 그랬나 라는 생각도 들었다.

1개의 댓글

comment-user-thumbnail
2022년 5월 9일

ref를 안쓰고도 비제어 컴포넌트를 다룰 수 있을지도??

답글 달기