-
[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를 사용하는 법을 나중에 더 정리해도록 하겠습니다. 조금 더 효율적인 스타일 컴포넌트 구성을 위해 우리 모두 화이팅합시다!
'Front-end > React' 카테고리의 다른 글
[styled-component] ThemeProvider로 다크모드 구현해보기! (0) 2022.04.13 [React-query] 리액트 쿼리를 사용해보자! (0) 2022.03.29 [Typescript,React] Typescript로 Form,UseState 사용해보기 (2) 2021.12.14 [React] 리액트 꿀라이브러리 탐방 (1) 2021.12.08