프론트엔드 데브코스 5기 MIL (4)

jh·2024년 1월 23일
1

주제 선정

이번 프로젝트의 경우 제공되는 API가 한정적이었기 때문에, 그에 맞게 주제를 선정할 수 밖에 없었다.
그래서 내가 생각한 내용은, 타이머 기능을 통해 자신이 하루동안 공부한 시간을 체크하고, 이를 기록으로 남길 수 있는 서비스를 개발해보고 싶었다

다행히 팀원들도 내 아이디어에 동조해 주어서, 이 주제를 가지고 개발에 들어갔다.

우리가 구현하고 싶었던 메인 기능은

  • 유저가 타이머를 통해 자신이 원하는 공부 시간을 등록할 수 있음
  • 타이머 동안 공부를 완료하면, 달력에 기록이 남음
  • 이 달력을 유저들끼리 서로 볼 수 있음
  • 유저의 공부 시간을 랭킹 시스템을 통해 비교할 수 있음
  • 회고 작성 기능이 있어 간단하게 오늘 공부에 대한 회고를 기록할 수 있음
  • 이 밖에 SNS 서비스 기능(메시지,팔로우 등등...)

하지만 개발을 진행하면서, 점차 기능이 몇 가지씩 빠질 수 밖에 없었다..

  • 랭킹 시스템의 경우, 기준이 있어야 하는데(일간,주간 등등) 이를 위해서는 더 세부적인 데이터를 서버에 저장하고, 받아와야 했는데 여건 상 불가능

  • 타이머의 경우에는 보통 스마트폰에서는 다른 앱 위에 표시 같은 권한 설정을 통해 꼭 화면에 켜놓지 않아도 시간이 가는데, 웹의 특성 상 그런 기능이 가능하지가 않았다(사실 알아 볼 시간이 별로 없었다)

  • 이 밖에도 디테일한 세부 사항들을 많이 빼게 되어서, 그 부분이 아쉬웠다...

하지만 중간에 빼는 것이 아니라 처음부터 이러한 기능은 안된다 라고 못 박고 갔어야 하는 게 맞는 것 같다.
주어진 환경에서, 이 기술이 구현이 가능할지 아닐지를 판단하는 것도 개발자의 능력인 걸 잘 느낄 수 있었다.

기술

약 3주 정도의 시간이 주어졌지만, 크리스마스 및 새해가 껴 있었기 때문에 체감 상 주어진 시간은 더 적었던 것 같다.
이러한 점을 고려해, 최대한 익숙하면서 핵심적이고, 어렵지 않은 기술들만 선정하여 기능 개발에 초점을 맞추었다.

Charkra UI

우리 팀은 이번에 Charkra UI라는 스타일 라이브러리를 도입했다.
사실 이것보다 더 유명한 스타일 관련 라이브러리가 많다(tailwind, headless UI 등등..)

내가 생각하는 Charkra UI의 장점은 개발하는 입장에서 편리하다 라고 생각한다.
tailwind의 경우 className에 때려박는 방법이기 때문에, 유연하게 사용하기 위해서는 tw macro 등 다른 패키지를 이용해야 한다.
하지만 charkra의 경우 외부에서 스타일을 주입해주기가 정말 편하다

const Component = ({...props}) => {
	return <div style={...props}><div/>
}

이렇게 Component 라는 컴포넌트에 외부에서 props 를 통해 스타일을 주입해주려면 Component에서 props의 type을 지정해줘야 한다

  • 이렇게 되면 정해진 props밖에 외부에서 주입해줄 수 밖에 없다.

  • 물론 ...props 를 통해서 여러 속성을 한번에 적용할 수 있지만, 저 props에 대한 이름과 타입을 모두 지정해줘야 타입 오류가 나지 않는다

interface  ComponentProps {
a: string
b: string
display? : string
border? : string
  ....
}
<div {...props}/> 

이럴때 charkra UI에서 제공하는 Props를 사용하면 편리하다

  • 해당 컴포넌트에 대한 스타일 속성에 대한 type을 모아놓은 것
import { Box , BoxProps } from '@chakra-ui/react'
interface ComponentProps extends BoxProps {
  a : string
  b: string
}
const Component = ({a,b,...props} : ComponentProps) => {
	return <Box {...props}></Box> 
}

이렇게 하면 a와 b를 제외한 다른 props는 Box(div 태그) 의 style 관련 속성으로 가능한 값들만 넣을 수 있게 타입 체크가 된다.

<Component a='1' b='2' display='flex' border=''/>//

이 방식으로 가장 부모 태그의 Layout 속성은 외부에서 주입해서 유연하게 스타일 관련 수정이 가능했다
Ex)해당 컴포넌트의 전체 width,height나 Flex의 gap,정렬 방향 등

외부에서 주입하는 게 무조건 좋을까?

프로젝트를 시작하기 전에는 재사용 가능한 컴포넌트에 꽂혀서, 속성을 외부에서 props를 통해 전달하는 게 무조건 좋다고 생각했다.

인스타그램

이것과 비슷한 컴포넌트를 만들어야 하는 일이 있었다.
단순히 저렇게만 사용하는 게 아니라,

  • 사진과 닉네임만 보여주는 컴포넌트
  • 제일 오른쪽에 버튼이 추가 된 컴포넌트
    등 다양하게 분기처리가 필요한 경우가 생겼다

그래서 만들다 보니

interface UserContentBlockProps extends FlexProps {
  href?: string;
  userImage?: string;
  userImageSize?: string | number;
  username: string;
  usernameFontSize?: string | number;
  isOnline?: boolean;
  content: string;
  ellipsis?: number | number[];
  subContent?: string;
  contentFontSize?: string | number;
  onImageClick?: () => void;
  onSubContentClick?: () => void;
}

props가 최대 12개가 들어가게 되었다
처음에는 되게 좋은 방법이라고 생각했다. props명도 의미를 알 수 있게 잘 되었고, 저렇게 이미지 + 글씨를 보여줘야 하는 컴포넌트가 필요한 경우를 다 해결할 수 있었다

하지만 곧 문제점이 드러났다
나는 저 컴포넌트를 합성 컴포넌트에서 사용하고 있어, 안그래도 길이가 길어질 수 밖에 없는 합성 컴포넌트 + props 가 각 한 줄씩 차지하게 되니 코드의 길이가 감당이 안되었다

또한 너무 과도하게 외부에서 컨트롤 하는 값들이 많아지다 보니,

  • content에 string 이 아니라 element 를 넣고 싶다 -> props 추가
  • clickEvent 를 다른 영역에도 주고 싶다 -> props 추가

이렇게 되어버렸다..

그래서 내린 결론

  • 아무리 비슷한 컴포넌트여도, 분기처리가 너무 많아지면 따로 만드는 게 좋다

  • 통일할 건 미리 통일하자
    - 현업에서는 저런 userImageSize usernameFontSize 같은 경우는 미리 통일을 시켜버리는 편이라고 한다.

    • fontSize 의 경우 혹시 개발 과정에서 숫자만 넣을 수도 or px을 붙여서 문자열로 쓸 수 있다는 생각에 타입을 두 개 다 허용했는데, 사실 우리끼리 개발하는 입장에서 그냥 하나로 통일해버려도 된다(어차피 ts에서 미리 알려줌)

사용하는 사람 입장에서 고민없이 정해진 컨벤션으로 사용하는 것도 DX관점에서 중요

ErrorBoundary

이번 프로젝트의 경우
A 요청에 대한 에러
401 - 인증
402 - 데이터 없음
...
이러한 문서가 있는게 아니어서, 처음에는 애를 좀 먹었다.
특히 react-query v3를 사용하고 있어서, onSuccess onError 같은 콜백을 이용하려고 했으나 상위 버전에서는 이러한 콜백 옵션이 사라진다고 하고, 이것 만으로는 뭔가 유저에게 에러에 대한 정보를 보여주는 게 좀 힘들다는 생각이 들었다.

  • ErrorBoundary 도입
    이러한 기능이 있는 건 알았지만, 언뜻 보기에는 러닝커브가 조금 있어보여서 도입을 안 하려고 했다. 하지만 에러에 대한 정보가 너무 없어서
    차라리 이럴거면 에러 발생 시 화면이 뻗지 않게 함 + 전역에서 공통적인 에러 처리를 할 수 있게 하는 게 좋지 않을까 찾아보던 중, react-error-boundary 라는 패키지가 있다는 걸 알게 되었다.

굳이 다운받지 않아도 custom하여 Errorboundary 기능을 사용할 순 있지만, class형 컴포넌트로 만들어야 하고 엄청난 기능을 제공하는 게 아니라 단순히 에러에 대한 전역 처리만 하는 걸 목표로 삼았기 때문에 라이브러리를 이용했다

또한 react-query와 궁합이 잘 맞는다는 생각이 들었다.
여기에 Suspense까지 같이 사용해서

  • 컴포넌트에서는 정상적으로 데이터가 들어올 걸 가정하고 뷰 로직만 담당
  • Suspense에서는 로딩에 대한 화면만
  • ErrorBoundary에서는 에러 발생 시 화면(엄밀히 말하면 fallback props)

이렇게 역할을 나눌 수 있어 매우 유용하게 사용하였다.

마무리

힘든 점도 많았지만, 개인적으로는 얻어가는 게 매우 많았다는 생각이 든다.
다음 프로젝트 전까지

  • react query 공부
  • github action 사용해보기
    등을 할 계획이다

0개의 댓글