styled-components 에서 destructuring 하기.til

Universe·2023년 4월 4일
0

dropdown 컴포넌트를 만드는데 다른 팀원분들도 사용할 수 있도록
어느정도 커스텀 선택지를 주고 싶었다.
그래서 생각한게

const StyledDropdown = {
  Container: styled.div`
    position: relative;
    display: inline-block;
  `,

  Button: styled.button`
    ${textVariants.H3_SemiBold}
    display: flex;
    justify-content: center;
    align-items: center;
    background: ${({ theme }) => theme.color.grayScale[25]};
    color: ${({ theme }) => theme.color.grayScale[500]};
    border: ${({ theme }) => `1px solid ${theme.color.grayScale[200]}`};
    border-radius: 40px;
    padding: 12px 21px;
    cursor: ${({ isReadOnly }) => (isReadOnly ? "auto" : "pointer")};

    ${({ buttonStyle }) =>
      buttonStyle &&
      css`
        ${buttonStyle.bgColor && `background: ${buttonStyle.bgColor}`}
        ${buttonStyle.color && `color: ${buttonStyle.color}`}
        ...
      `}
  `,
};

이런식으로 buttonsStyle props 를 객체로 받아서
key 값에 해당하는 css를 덮어 씌운다는 느낌.
지금 생각해봐도 정말 기특한 생각이 아닐 수 없다.
그런데 잘 보면..

    ${({ buttonStyle }) =>
      buttonStyle &&
      css`
        ${buttonStyle.bgColor && `background: ${buttonStyle.bgColor}`}
        ${buttonStyle.color && `color: ${buttonStyle.color}`}
        ...
      `}

보기에 불편하다.
일일히 buttonStyle.~~ 하고 달아줘야 한다니 !
그래서 어떻게 하면 styled-components 안에서 구조분해할당을 할 수 있을지 고민해봤다.

${({
      buttonStyle: { bgColor, color, borderColor, borderRadius, padding },
    }) =>
      css`
        ${bgColor && `background: ${bgColor}`}
        ${color && `color: ${color}`}
        ${borderColor && `border: 1px solid ${borderColor}`}
        ${borderRadius && `border-radius: ${borderRadius}`}
        ${padding && `padding: ${padding}`}
      `}
      

이 방식은 일반적인 구조 분해 할당과 비슷하지만, 함수 인자로 전달되는 객체를 구조 분해하는 방식이다.
객체는 함수의 인자로써 전달된다.
인자를 구조분해 할 때는 위와 같은 방식으로 할 수 있다는 것이다.
자바스크립트 공부를 소홀히 하면 안되는 이유를 여지없이 보여주는 사례가 아닐 수 없다.
왜 한가지 방법밖에 생각을 못했지? 😢
오늘 두시간 가까이 이 문제와 씨름을 했으므로 까먹진 않을 것 같다.





그런데..

조금 더 생각을 해 보니까 굳이 저런식으로 할 필요가 없다.
애초에 저런식으로 설계를 하면 theme provider도 사용할 수 없을 뿐더러
옵션을 전부 지정해주고 기억해야 하니까 오히려 훨씬 불편하다.
그래서..

  Menu: styled.div`
    ${textVariants.Body1_SemiBold}
    display: ${({ isOpen }) => (isOpen ? "block" : "none")};
    position: absolute;
    border: 1px solid ${({ theme }) => theme.color.grayScale[200]};
    border-radius: 12px;
    padding: 8px 0;
    min-width: 160px;
    z-index: 1;
    ${({ menuStyle }) => menuStyle}
  `,

이런식으로 수정했고,


const menuStyle = css`
    //css 코드
  `;


<Dropdown
  buttonLabel="09시~10시"
  isReadOnly={false}
  menuStyle={menuStyle}
>

이런식으로 아예 css 객체를 할당하는 식으로 변경했다.
'커스텀을 자유롭게 할 수 있도록 한다' 는 취지에서 이쪽이
css 스니펫도 사용할 수 있으면서, theme Provider 도 사용할 수 있다는 것이
큰 장점.

profile
Always, we are friend 🧡

0개의 댓글