[Book Buddy / Error Note] 반응형 MediaQuery를 모듈화 해서 styled-components에 사용할 경우 props 타입 에러

메인 프로젝트(Ez to Play)때 해결 못 했던 문제를 이번 프로젝트에서 해결했다. 

정말 너무 별 거 없어서 어디 가서 해결했다고 말하기도 창피한 문제긴 하다.  

 

메인때도 반응형 페이지를 만들기 위해 media query를 사용했는데, media query를 모듈화 해서 썼었다. 

media query를 모듈화 하게 되면 속성을 하나의 파일에서 관리하므로 유지보수가 편리하다. 

 

해결 못 했던 문제

하지만 당시에는 props로 사이즈를 받아오는 경우 만들어둔 media query 모듈을 어떻게 적용해야 하는지 방법을 찾지 못 했고, 

 

 

(아마 저 props 타입 에러를 해결하지 못 했던 것 같다.)

 

interface StyleDivProps {
  height: 140 | 60;
  imageurl: string;
}

export const Styled_HomePageButton = {
  Container: styled.button<StyleDivProps>`
    height: ${props => props.height}px;
    
   // 일반 미디어 쿼리 (@media) 사용
    @media screen and (min-width: 820px) { 
      height: calc(${props => props.height}px * ${screenScale.tablet});
    }
  `,
};

 

위 코드처럼 prop로 들어오는 코드가 있으면 그 부분만 일반 미디어 쿼리 (@media) 를 사용하는 것으로 해결했었다.

당시에는 props로 들어오는 곳이 저 한 군데 밖에 없었지만, 이런 경우가 많아지면 많아질 수록 media query를 모듈화 한 의미가 없어지기 때문에, 이번 프로젝트에서는 이 문제를 해결하고 싶었다.

 

해결한 방법

해결 방법은 별 것 없고 props에 타입을 주기만 하면 된다.

any로 주어도 되지만 해당 태그에서 사용하고 있는 props를 그대로 사용하면 된다.

 

아래는 이번에 작성한 코드다.

 

interface StyledRedButtonProps { // 아래 태그에서 사용하고 있는 props
  height?: number;
  width?: number;
}

export const Styled_RedButton = {
  Button: styled.button<StyledRedButtonProps>` // StyledRedButtonProps 사용
    height: ${props => (props.height ? `${props.height}px` : '56px')};

     ${DeviceQuery.bigScreen`
      height: ${(props: StyledRedButtonProps) =>  // 똑같이 StyledRedButtonProps 사용
        props.height
          ? `calc(${props.height}px / ${screenScale.bigScreen})`
          : `calc(56px / ${screenScale.bigScreen})`};
    `}
  `,
};

 

끝~

 

1분만에 해결했는데 도대체 메인 때는 왜 이걸 못 했을까?

이번 프로젝트를 하면서 타입스크립트에 좀 더 익숙해진 것 이라고 생각해야겠다.. 🥲

 

 

추가로 만들어둔 미디어 쿼리 모듈을 적용할 때에는 위처럼 props 값, 기본값 따로 적용해도 되고 한 번에 적용해도 된다. 

 

1. 따로 적용

${DeviceQuery.bigScreen`
  height: ${(props: StyledRedButtonProps) =>
    props.height
      ? `calc(${props.height}px / ${screenScale.bigScreen})`
      : `calc(56px / ${screenScale.bigScreen})`};
`}

2. 한 번에 적용

  ${DeviceQuery.bigScreen`
    height: calc(${(props: StyledRedButtonProps) =>
      props.height ? `${props.height}px` : '56px'} / ${ screenScale.bigScreen }
    );
  `}