2021.04.22 데일리 회고

천영석·2021년 4월 22일
2

Facts

  • 카드 컴포넌트를 리팩토링했다.(2시간)
  • props에 대해 고민을 했다.(3시간)
  • 인풋 컴포넌트를 만들었다. (1시간)

Feelings & Findings

카드 컴포넌트를 리팩토링했다.

우리가 만든 기존의 카드 컴포넌트는 약간의 문제가 있었다. 재사용성에 관한 것이다. 재사용에 관한 완전한 합의가 되지 않은 상태로 구현을 하다 보니 문제가 발생했다. 카드 컴포넌트는 우리 App에서 사용하도록 구현이 되어 있었다. 즉, 카드 컴포넌트 안에 스타일로 카드 칩이나 소유자 이름, 만료일 등 여러가지 스타일이 적용되어 있었다.

문제는 카드 추가 버튼을 만들 때 발생했다. 카드 추가 버튼은 빈 카드에 + 버튼만 존재했고, 우리의 카드 컴포넌트는 이미 스타일을 모두 가지고 있기 때문에 새로운 카드 컴포넌트를 만들어야 했다. 기존의 카드 컴포넌트에서 조건부 랜더링으로 가능하긴 했지만 좋은 방법이 아니라고 생각했다. 왜냐하면 카드 컴포넌트의 역할이 아닌 것 같다는 의견이 있었기 때문이다. 다들 이 의견에 동의를 했고, 근본적인 부분에 문제가 있지 않을까를 고민하게 되었다.

재사용성에 관해 우리만의 기준을 정하기로 했다. 우선 기준은 페이먼츠 App이 아닌 다른 곳에서 사용될 만큼 범용적인 컴포넌트가 아닌 페이먼츠 App에서 쓰이도록 구현을 하도록 했다. 아무 App에서 사용할 수 있게 하려면 고려해야 할 사항이 너무 많고, 오히려 미션의 의도가 아닌 것 같다는 생각 때문이었다. 우린 페이먼츠 App을 만들고 있는데, 로또 App에서도 사용할 수 있는 컴포넌트를 만들어야 한다는 것이 아닌 것 같았다.

이렇게 정의를 하고 보니 카드 컴포넌트 자체가 잘못된 것이었다. 현재 App에서 자주 사용되는 카드의 구조(틀)를 컴포넌트화 하고, 칩이나 소유자 이름 등 스타일이 들어가야 하는 것은 CreditCard 컴포넌트로 구현을 했다. 이렇게 하고 보니 CreditCard 컴포넌트에서는 Card 컴포넌트를 사용하고 있었고, 카드 추가 버튼에서도 Card 컴포넌트를 사용하고 있었다. 여기에서 리액트 공식 문서에 나와 있는 컴포넌트를 잘게 쪼개는 것을 두려워하지 마세요. 라는 말의 의미를 알게 되었다.

의미 있는 토론이었고, 좋은 결론을 냈다고 생각한다.

props에 대해 고민을 했다.

이 부분도 정말 많인 고민을 했다. 사건의 발단은 common 컴포넌트들을 우리가 원한다면 커스터마이징할 수 있게 들어온 props를 모두 style에 적용해주고 있는 것으로 시작되었다.

// Button.js
export const Button = ({ children, ...props }) => {
  return <Styled.Button {...props}>{children}</Styled.Button>;
};

// Button.style.js
const Styled = {
  Button: styled.button((props) => ({
    color: '#000',
    fontWeight: '700',
    fontSize: '14px',
    ...props,
  })),
};

위와 같은 코드를 사용해서 style에서 props로 들어온 모든 값을 적용하도록 했다. 부작용으로는 style 요소가 아닌 다른 무엇이든 들어올 수 있다는 것이었다. onClick을 넣을 수도 있고, abc도 넣을 수 있고, 뭐든 할 수 있었다. 또한, 위의 상황에서 styled-components의 props에는 theme과 children이 할당되어 있었다. 이건 우리가 원하는 것이 아니었다.

하지만 css의 특성 상 자신들의 속성이 아니라면 무시하기 때문에 에러가 발생하지는 않았지만, 개발자 도구를 열어봤을 때 너무 찝찝했다. 그리고 절대 에러가 발생하지 않을까라는 물음에도 답할 수 없었다.

그래서 Button 컴포넌트를 사용할 때 styles라는 props로 넘겨주어서 Button에서는

export const Button = ({ children, styles }) => {
  return <Styled.Button styles={styles}>{children}</Styled.Button>;
};

이렇게 받는 방법을 생각했다. 물론 styles에 이상한 값을 할당하면 그대로 들어가겠지만 constants 파일에 있는 것들은 DeepFreeze를 굳이 하지 않아도 개발자는 이것을 변경하면 안되는 것을 알기 때문에 styles라는 props에도 style 값이 아닌 다른 값을 할당하지 않을 것이라는 생각 때문이었다. 하지만 depth가 깊어지는 것이 마음에 들지 않는다는 의견이 있었고, 이렇게 해도 결국 문제를 한 번 회피한 것이지 완전히 해결하지는 못하는 것 같다는 의견이 있었다.

오랜 시간 토론 끝에

export const Button = ({ children, ...props }) => {
  return <Styled.Button styles={props}>{children}</Styled.Button>;
};

// Button.style.js
const Styled = {
  Button: styled.button(({ styles }) => ({
    color: '#000',
    fontWeight: '700',
    fontSize: '14px',
    ...styles,
  })),
};

이렇게 구현하기로 했다. Button을 사용하는 쪽에서는 바로 width="100%"와 같이 사용할 수 있고, styled-components에 사용할 땐 넘어온 styles만 받기 때문에 위의 props에 theme과 children과 같은 이상한 값이 들어오는 것을 막을 수 있다. 완벽하게 좋은 방법은 아닐 수 있지만 여기에서 만족하고 넘어가기로 했다. 커스터마이징을 포기할 수는 없었다.

인풋 컴포넌트를 만들었다.

인풋 컴포넌트는 생각보다 간단했다. 인풋 컴포넌트는 기능 구현이 어려울 것 같다. 그리고 4개의 인풋을 합쳐서 하나의 인풋처럼 보이게 만들어야 하는데, 이 과정도 쉽진 않을 것 같다. 아마 내일 하게될 것이다. 아직 인풋 컴포넌트는 완벽하게 하지 못해서 내일 글을 작성할 것 같다.

Plans

  • 인풋 컴포넌트 마무리하기
  • 기능 구현 시작하기
profile
느려도 꾸준히 발전하려고 노력하는 사람입니다.

0개의 댓글