TIL28. 재사용 가능한 컴포넌트에 대한 고민들

imloopy·2022년 5월 31일
0

Today I Learned

목록 보기
31/56

재사용 컴포넌트를 만들 때 고려사항

아래 내용들은 어떤 레퍼런스가 아닌, 공부하면서 이런 식으로 메뉴얼을 구성하여 컴포넌트를 구성할 때 좀 더 주의를 기울였으면 좋겠다고 생각한 것들을 적은 것이니(뇌피셜), 필요 없다면 넘어가셔도 좋은 내용입니다.

  1. 각 컴포넌트가 하나의 목적만 이룰 수 있도록, 컴포넌트가 책임질 바운더리를 구성 (함수를 작성하는 것과 동일)
  2. 컴포넌트를 재사용(동적으로 사용)하기 위하여 재사용할 범위를 prop으로 구성
    1. title를 동적으로 구성할 거면 title을 prop으로 받고, color를 동적으로 구성할 거면 color를 prop으로 받는 방식
    2. 스타일을 바꾸기 위하여 꼭 해당 style을 prop으로 받아야 할 필요는 없음 → error 프롭이 true일 경우, 빨간색을 나타내도록 할 수도 있다. 이 경우, style 자체가 error라는 속성에 종속되므로 style을 완벽하게 재사용하지 않는다면, 해당 style 속성을 프롭으로 받을 필요는 없다.
  3. 상속 대신 합성 모델 사용하기.
    1. 합성 모델의 대표적인 prop인 children prop을 사용할 수 있다
    2. children 프롭은 범용적인 박스 역할을 하는 layout prop이나, 어떠한 엘리먼트들이 들어오는지 정확하게 알 수 없는 경우 사용할 수 있다.
    3. 또한, children을 가공하기 위한 특별한 역할이 필요할 때, children프롭을 사용할 수 있다.
    4. JSX.Element를 받을 때에는 children, 데이터를 받을 때에는 prop을 이용하면 될 듯?
  4. 객체 지향 프로그래밍의 개념인 구현과 API를 분리하는 방법은 컴포넌트에서 동일하게 적용된다.
    1. 예를 들어, 드래그 하여 파일을 추가할 수 있는 컴포넌트를 만든다고 가정
    2. 구현 영역: 드래그 이벤트 감지 등 사이드 이펙트 처리, 드래그 상태 정의
    3. API 영역: 드래그가 발생했을 때 처리해야 할 이벤트(재사용하기 위해 프롭으로 전달)
    4. 드래그 로직이 길어지거나, 재사용 가능성이 있다면 hooks를 이용하여 분리하기.
  5. 리액트 컴포넌트는 함수로 구성되어 있어 쉽게 재구성이 가능하기 때문에, 처음부터 완벽한 컴포넌트를 만들기 위한 부담감을 버리자.
    1. 페이지부터 만들고, 잘 동작하고 재사용할 만한 것들을 컴포넌트로 만들어보자.
    2. 이 프롭이 필요하다 싶으면 나중에 추가해보자
    3. 이 과정이 익숙해지면 컴포넌트를 만드는 과정이 점점 빨라질 것이다.

오늘 배운 것들

  • Avatar 및 AvatarGroup 컴포넌트
  • Slider 컴포넌트
  • Progress 컴포넌트
  • Skeleton 컴포넌트
  • Input 컴포넌트
  • Select 컴포넌트

Avatar 및 AvatarGroup 컴포넌트

  • 사용자가 등록한 사진을 보여주는 Avatar 프롭이다.
  • 재사용성을 높이기 위하여 alt, src, size, shape, placeholder 프롭을, lazy loading을 위한 lazy, placeholder 프롭을 넣어주었다.
  • 이 placeholder는 이미지가 로딩중일 때 보여주는 placeholder 목적으로 구현했으나, 만약 사용자가 등록한 프로필 사진이 없을 때 이 placeholder를 보여주고, 외부 wrapper에서 로딩 중일 때 placeholder 컴포넌트를 자체적으로 보여줘도 될 듯 하다.

Slider 컴포넌트

  • 볼륨 조절처럼 마우스를 클릭하여 옮길 경우 핸들이 이동하는 컴포넌트이다.
  • 재사용성을 높이기 위해 step, min, max와 움직이면서 실행할 onChange 콜백 함수를 프롭으로 받도록 하였다.
  • 사용자 경험이 향상되도록 mousedown은 sliderRef 컴포넌트에 걸어주었고, mousemove와 mouseup 이벤트는 document 전체에 이벤트 리스너를 감지하도록 하였다.
  • 근데 최적화가 안되있는지, 빠르게 왔다 갔다 할 경우 원활하게 움직이지 않았고, 마우스를 손에서 땠음에도 불구하고 핸들이 따라 움직이는 현상이 있었다. 조금 더 고민해봐야겠다.

Progress 컴포넌트

  • 만드는 방법은 Slider와 비슷하다. Container와 rail, track으로 이루어져있다. 이 컴포넌트들은 서로 종속적이므로 하나의 컴포넌트로 구성해도 무방하다. 스타일을 입히기 위하여 각각 styled component로 구성하였다.
  • 애니메이션을 입히고, transition을 이용하여 width가 변할 때 부드럽게 이동하도록 하였다. width를 0으로 잡고, value prop을 이용하여 퍼센트를 동적으로 구현하도록 하였다.

Skeleton 컴포넌트

  • 스켈레톤은 요즘 유튜브 로딩시나, velog에서 글을 불러오는 중, 빈 화면이나 스피너 대신 이 자리에 컨텐츠가 존재한다고 알려주는 컴포넌트이다.
  • 가장 기초가 되는 Base 컴포넌트에 애니메이션과 색상, border-radius의 값을 정의하고, 두 가지 shape로 구성하여(Box, Circle) Base를 상속하는 방식을 사용하였다.
  • 현재는 index.tsx에서 Skeleton을 묶어서 Box, Circle컴포넌트를 export하는데, 차라리 동적 태그로 구성하면 좀 더 깔끔하게 구성할 수 있을것 같다는 생각을 했다.
  • paragraph 스켈레토는 Box 컴포넌트를 이용하여 map으로 구성하고 있다. 유튜브나 velog처럼 하나의 줄에서 여러 조각으로 나누어서 표현하는 방식도 조금 더 생각하면 구현할 수 있을 것 같다.

Input 컴포넌트

  • input 컴포넌트는 일반적으로 재사용성을 높이기 위해 Wrapper와 함께 사용한다. 또한, Input 컴포넌트의 width를 100%로 지정해놓고 wrapper의 너비를 조정하는 방법으로 너비를 조정한다.
  • input의 재사용성을 높이기 위하여 (disabled, required, readOnly, inValid) 등의 프롭들을 받도록하였고, input 자체는 로직을 처리할만한 것이 없기 때문에 별도로 구현 영역은 구현하지 않았다.
  • 현재 onChange를 프롭으로 받도록 안했는데, 실제로 컴포넌트를 사용하기 위해서 이를 프롭으로 받도록 하는 것이 좋겠다.

Select 컴포넌트

  • Input 컴포넌트처럼 Select 역시 재사용성을 고려하기 위하여 block, inline-block을 결정하는 wrapper를 만들고, Select 컴포넌트 자체는 width를 100%로 고정하여 구성한다.
  • option을 데이터로 입력 받고, option 컴포넌트를 내부에서 처리하도록 하였다. Avatar와 AvatarGroup과 달리 데이터를 프롭으로 받아서 처리하는 이유는 다음과 같다고 생각한다.
    • data로 처리하는 것이 더 적합(AvatarGroup과 달리 View적 요소가 없고 오직 데이터만 존재)
    • Select 자체가 어떤 컴포넌트를 감싸기 위한 wrapper가 아님
  • 흥미로웠던 것은, placeholder를 프롭으로 입력받아 아무것도 선택하지 않았을 때에는, placeholder가 보이게하고, placeholder 옵션에 hidden 속성을 주어 어떤 것을 하나라도 선택하면 select에서 보이지 않게 하는 것이었다.
  • 또한, placeholder의 값이 selected 값으로 선택되지 않도록 잘 걸러주는 작업을 해야 한다. select 값이 변할 때 핸들러 onChange를 프롭으로 받아서 선택된 데이터를 받을 수 있다.

느낀 점

  • Vue가 끝나고 리액트를 시작하니, 이전에 리액트는 해봤지!하고 만만하게 접근했는데, Vue가 체감상 훨씬 쉬운 것 같다… Vue는 프레임워크고 리액트는 라이브러리라 그런지 너무나 자유도가 높아서 오히려 더 체계 잡는 것이 어려운 것 같다.
  • 그래도 처음에는 막막했는데, 계속 실습을 진행하고, 생각의 흐름을 정리고 기록해나가면서 어느정도 틀이 잡히기 시작한 것 같다. 그래도 커스텀 hooks 같은 부분은 좀 더 연습이 필요할 듯 하다.
  • 기록은 언제나 도움이 된다. 미래의 나를 위해서 조금 더 고생하는 습관을 들이자!

출처

0개의 댓글