[styled-components ] 깔끔한 조건처리 - #리액트 2차 개인과제 리팩토링

간단한 과제 소개

  • 포켓몬 데이터 목록을 이용하여 나만의 포켓몬을 추가/삭제할 수 있다. 
  • 포켓몬 상세 정보를 확인할 수 있다.

 


사진이 잘 안보여서 버튼이 잘 안보일 수도 있는데 사진 아래 빨간색으로 보이는게 버튼이다. 이번 프로젝트에서 버튼 종류라고 해봐야 검은색, 빨간색 2종류가 있다. 근데 고작 2개의 조건처리를 하는데도 묘한 불편함을 느꼈다(가독성이 특히).  그러다 찾은게 styled-components의 {css} 라이브러리인데 내가 느끼던 불편함을 딱 알맞게 해소해줄 수 있는 녀석이었다. 

 

 

💡 기존 styled-components의 조건 처리

일단 기존의 `styled-components` 로 조건에 따른 스타일을 변화하려면 다음과 같이 작성해야한다.  `styled` 내부에서 삼항연산자를 사용하거나, 함수를 만들던지, 객체를 만들어서 매핑을 시켜준다던지.. 그 중에 그나마 편한 방법으로 쓰고 있었다. 

 

일단 기존 코드들을 확인해보자. 

 

📍 삼항연산자

<StBtn type={'warn'}>
  {text}
</StBtn>

const StBtn = styled.button`
  background-color: ${props => props.type === 'warn' ? 'red' : 'white'};
  color: ${props => props.type === 'warn' ? 'white' : 'black'};
  border: none;
  padding: 3px 5px 3px 5px;
  border-radius: 4px;
  `;

문제점

조건으로 처리하는 속성이 2개만 있어도 복잡하고 보기 싫게 생겼다. 그래서 함수로 분리해보았다.

 

📍 함수에서 조건 처리 (1) - 모든 속성마다 함수 정의

/* 생략 */
const getBgColor = (type) =>{
  switch(type){
    case 'warn':
      return 'red';
    default:
      return 'white'
  }
}

const getColor = (type) => {/* 생략 */}

const StBtn = styled.button`
  background-color: ${props => getBgColor(props.type)};
  color: ${props => getColor(props.type)};
  border: none;
  padding: 3px 5px 3px 5px;
  border-radius: 4px;
`;

뭐 대충 이렇게 사용하던가 해야한다. 개인적으로 삼항 연산자보다는 쪼~끔 더 괜찮게 생긴 것 같다. 

 

문제점

하지만 같은 타입인데도 필요한 속성마다 함수를 전부 정의하고, 호출하는건 꽤나 불필요한 작업이라고 생각한다. 그래서 이번에는 하나의 함수에서 타입별로 분기가 필요한 모든 속성을 반환하도록 합쳐보았다.

 

📍 함수에서 조건 처리 (2) - 하나의 함수에서 전부 반환

const getButtonStyles = (type) => {
  switch (type) {
    case 'back':
      return {
        backgroundColor: 'black',
        color: 'white',
      };
    default:
      return {
        backgroundColor: 'red',
        color: 'white',
      };
  }
};

const StBtn = styled.button`
  ${({ type }) => {
    const styles = getButtonStyles(type);
    return `
      background-color:${styles.backgroundColor};
      color:${styles.color};
  `;

 

어처피 공통 변수 type으로 분기를 처리하니 하나의 함수에서 backgroundColorcolor 를 전부 반환하도록 변경했다.  개인차가 있겠지만 이전 코드들에 비해서는 깔끔해졌다고 생각이 든다. 특히 type 별 속성에 대한 스타일을 하나의 블록안에서 처리가 가능해졌다는게 가장 큰 장점이 아닐까 싶다. 

그래도 초보 개발자의 시선에서 코드가 팍 하고 바로 읽히지는 않는 것 같다. 따라서 styled-components의 `css` 라이브러리를 함께 import해서 변경해보았다. 

 

 

💡 styled-components의 {css} 라이브러리 사용

import styled, { css } from 'styled-components';

const COLORS = {
  warn: css`
    background-color: red;
    color: white;
  `,
  default: css`
    background-color: black;
    color: white;
  `,
};

const StBtn = styled.button`
  ${(props) => props.colorStyle}
  border: none;
  padding: 3px 5px 3px 5px;
  border-radius: 4px;
`;

const Button = ({ text, type = 'default', id, action }) => {
  const colorStyle = COLORS[type];

  return (
    <StBtn colorStyle={colorStyle}>{text}</StBtn>
  );
};

코드가 정말 많이 깔끔해졌다.  사용법도 간단하다. 

  • css를 import한다.
  • 객체 형태로 type에 대한 map(객체)을 만들어준다. 
  • styled에서 반환하면 별도의 속성지정하지 않아도 알아서 바로 적용된다.

 

📍 변경 목적

  • 과제를 시작하기전부터 `styled-components`를 대충 배워 대충 쓰고 있었는데 처음 만난 순간부터 가독성이 별로 좋지 않다고 느껴졌었다. (익숙하지 않아서 그럴수도..)
  • 근데 아무리 봐도 고작 2개의 타입, 2개의 속성을 변경하는건데도 코드의 길이나 가독성이 매우 나쁘다고 생각했다. 
  • 하지만 `css` 라이브러리를 쓰면 우리에게 친숙한 css 문법을 그대로 가져가면서 `styled` 부분의 코드도 매우 짧게 해결할 수 있어서 바로 적용해보았다.

댓글

Designed by JB FACTORY