ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Styled-component] styled-component 좀 더 똑똑하게 쓰기
    Front-end/React 2021. 12. 13. 17:22

    안녕하세요. 오늘 포스팅할 주제는 'styled-component'입니다! 리액트를 사용하는 분이라면 다양한 css 라이브러리를 사용하실텐데 저는 CSS-IN-JS의 대표적인 라이브러리 중 하나인 styled-component를 사용 중입니다.

     

    하지만 요즘 styled-component의 재사용성을 제대로 사용하지 않는 저를 발견하고 styled-component의 다양한 기능과 재사용성을 더욱 심도있게 사용해보자라는 마음에 포스팅을 하게 되었습니다! 우리 모두 styled-component를 제대로 사용해 보도록 합시다!

     

    #1 Styled-component의 props전달을 잘 사용하자.

    같은 h2 태그를 가진 element를 사용해야 한다고 가정해보겠습니다. 둘 다 부제목이지만 다른 폰트 사이즈를 사용해야 한다면 우리는 어떻게 사용할 수 있을까요?

     

    물론, 같은 h2태그를 가진 styled-component를 만들어서 사용할 수도 있겠지만, font-size만 변경하면 될 경우 우리는 font-size가 바뀔때마다 새로운 컴포넌트를 만들어야하는 불필요한 행위를 해야합니다. 이런 단순 반복 작업을 피하기위해 우리는 styled-component의 props를 잘 사용해야 할 필요가 있습니다.

     

    나쁜 사용의 예

    const SubTitleFont = styled.h2`
    	font-size: 22px;
        font-weight: 600;
    `
    
    const SubTitleFont2 = styled.h2`
    	font-size: 24px;
        font-weight: 600;
    `
    
    function App() => {
    	return (
        	<section>
            	<SubTitleFont>부제목1</SubTitleFont>
                <SubTitleFont2>부제목2</SubTitleFont2>
            </section>
        )
    }

    이 것은 좋지 않은 styled-component의 사용 방식일 것입니다. 왜냐하면 많은 부분이 중첩되는 같은 컴포넌트를 두 개를 만들어 사용했기 때문입니다. 저도 styled-component를 전에 사용할 때 이런 식으로 사용하곤 했는데, 이 것은 좋지 않은 접근이죠. 따라서 우리는 props를 통해 font-size를 가변값으로 만들어 줄 수 있습니다!

     

     

    좋은 예

    const SubTitleFont = styled.h2`
        font-size: ${(props) => props.fontSize};
        font-weight: 600;
    `
    
    fuction App () {
    	return (
        	<section>
            	<SubTitleFont fontSize="22px">부제목1</SubTitleFont>
                <SubTitleFont fontSize="24px">부제목2</SubTitleFont>
            </section>
        )
    }

    이런 식으로 우리는 font-size를  props로 넘겨주어 가변값으로 만들어 필요 없는 h2 태그를 하나 줄여서 만들 수 있게 되었습니다.

     

    #2 styled-component.attrs

    styled-component를 사용하여 이미지 태그를 가지는 태그의 스타일링을 하던 도중입니다. 당신은 동일한 alt 속성을 가지는 이미지들을 작업 중이라면, 그저 image 태그의 스타일링 만을 한 후, 컴포넌트에 alt 속성을 부여하지 않을 수 있습니다. 👏🏻

     

    const ProdImage = styled.img`
        width: 100px;
        height: 100px;
    `
    
    function ProductItem() {
    	return (
        	<MainContainer>
                <ProdImage src='https://*****' alt='제품 이미지' />
                <ProdImage src='https://*****2' alt='제품 이미지' />
                <ProdImage src='https://*****3' alt='제품 이미지' />
            </MainContainer>
        )
    }

    ProdImage의 component를 사용하는 이미지는 공통적으로 alt에 '제품 이미지'라는 속성을 가지고 있습니다. 우리는 이 것을 styled-component의 attrs를 이용하여 해결할 수 있습니다!

     

    const ProdImage = styled.img.attrs({ alt='제품 이미지' })`
        width: 100px;
        height: 100px;
    `
    
    function ProductItem() {
    	return (
        	<MainContainer>
                <ProdImage src='https://*****'/>
                <ProdImage src='https://*****2'/>
                <ProdImage src='https://*****3' />
            </MainContainer>
        )
    }

    다음과 같이 ProdImage를 사용하는 컴포넌트들의 기본 속성 alt를 styled-component에서 선언해주어, 자동으로 우리는 ProdImage를 사용하는 컴포넌트들에 대한 속성을 부여할 수 있습니다! 👌🏻

     

    #3 styled-component를 확장하여 사용해보자.

    그런 경험이 있으신가요? 새로운 element의 스타일링을 하는데 위에 만들었던 스타일 컴포넌트의 대부분의 내용을 가져와야 하는 경우가 있었을 꺼라고 생각합니다. 예를 들어 border-radius만 추가 된다거나, box-shadow만 추가 된다거나 하는 일 말이죠. 이 때 우리는 그 전의 컴포넌트의 요소들을 참조하는 확장된 컴포넌트를 만들 수 있는 방법이 있습니다.

     

    const Memo = styled.div`
        width:300px;
        height:500px;
    `
    
    funtion Section2 () {
      return(
        <MainContainer>
          <Memo>Lorem Ipsum</Memo>
        </MainContainer>
      )
    }

    다음과 같은 Memo라는 이름의 스타일 컴포넌트가 있습니다. 우리는 이 메모 컴포넌트에 box-shadow를 부가하고 싶다면 어떡해야 할까요? 물론, ShadowMemo라는 컴포넌트를 하나 더 만들어 복사 붙여넣기 후 box-shadow 요소만 추가해주면 되지만, Memo와 같은 CSS를 공유한다면, 저 Memo를 확장하여 사용할 수 있을 것입니다.

     

    const Memo = styled.div`
        width:300px;
        height:500px;
    `
    
    const ShadowMemo = styled(Memo)`
        box-shadow: 2px 4px 8px;
    `
    
    funtion Section2 () {
      return(
        <MainContainer>
          <Memo>Lorem Ipsum</Memo>
          <ShadowMemo>Lorem Ipsum</ShadowMemo>
        </MainContainer>
      )
    }

    이렇게 하면 우리는 ShadowMemo에 box-shadow 요소만 추가해도 Memo를 확장해 ShadowMemo라는 Memo 컴포넌트를 확장한 새로운 컴포넌트를 만들 수 있습니다 🌈

     

    #4 유용한 선택자 with styled-component

    우리는 선언된 styled-component들이 자식요소와 부모요소로 섞여 있는 모습을 봅니다. 퓨어 css에서는 이 것을 스코프 안에 선택자 스코프로 처리를 하죠. styled-component는 자식요소에 대한 select를 어떻게 해야할까요? Container 컴포넌트 안에 있는 Box 컴포넌트에만 스타일을 추가하고 싶을 때 이러한 선택자는 굉장히 유용할 것 입니다.

     

     

    const MainContainer = styled.section`
        display:flex;
        width:100vw;
    `
    
    const Memo = styled.div`
        width:300px;
        height:500px;
    `
    
    const ShadowMemo = styled(Memo)`
        box-shadow: 2px 4px 8px;
    `
    
    funtion Section2 () {
      return(
        <>
        <MainContainer>
          <Memo>Lorem Ipsum</Memo>
          <ShadowMemo>Lorem Ipsum</ShadowMemo>
        </MainContainer>
          <Memo>Lorem Ipsum</Memo>
        </>
      )
    }

    다음과 같은 예시가 있습니다. 우리는 여기서 MainContainer 컴포넌트 안에 있는 Memo컴포넌트만 background-color를 black으로 바꾸고 color를 white로 바꾸고 싶다고 합니다. 여기서 우리는 MainContainer의 하위요소인 Memo만을 선택해 스타일을 부가할 수 있습니다.

     

    const Memo = styled.div`
        width:300px;
        height:500px;
    `
    
    const MainContainer = styled.section`
        display:flex;
        width:100vw;
        ${Memo} {
          background-color:black;
          color: white;
        }
    `
    
    const ShadowMemo = styled(Memo)`
        box-shadow: 2px 4px 8px;
    `
    
    funtion Section2 () {
      return(
        <>
        <MainContainer>
          <Memo>Lorem Ipsum</Memo>
          <ShadowMemo>Lorem Ipsum</ShadowMemo>
        </MainContainer>
          <Memo>Lorem Ipsum</Memo>
        </>
      )
    }

    다음과 같이 ${} JS를 사용하여 우리는 styled-component 내에서 select를 할 수 있습니다. MainContainer의 하위 요소의 Memo에만 우리는 스타일을 부가할 수 있습니다! 🍀

     

     

    styled-component를 조금 더 잘 이용하기 위해 많이 사용할 기능들을 정리해보았습니다. 새롭게 알게되는 styled-component를 사용하는 법을 나중에 더 정리해도록 하겠습니다. 조금 더 효율적인 스타일 컴포넌트 구성을 위해 우리 모두 화이팅합시다!

    댓글

sangjun's blog