이번 포스팅에서는 React에서 사용하는 Styled-Components에 대해서 이야기 해보려고 한다.
모든지 사용할 때 '왜?' 를 수반하는게 필요하다고 생각한다. 그럼 왜 Styled-Components일까?
먼저 Styled-Components를 사용하지 않는 컴포넌트를 살펴보자.
function App() {
return (
<div style={{display:"flex"}}>
<div style={{backgroundColor:"tomato", width:200, height:200}}>
<span>Hi</span>
</div>
<div style={{backgroundColor:"teal", width:200, height:200}}></div>
</div>
);
}
모듈을 통하거나 외부 css파일을 통해서 분리할 수 있지만 컴포넌트 내부에 Javascript 코드를 통해서 컴포넌트를 구성해봤다.
위 코드를 살펴보면 직관적이지 않다. 감싸고 있는 div 내부의 div가 어떤 역할을 하는지 알고싶다면 css를 살펴봐야한다. 또한 내부에 스타일 속성을 지정하면서 코드 또한 가독성이 떨어지게 된다. 물론 css를 분리할 수 있지만, css를 분리하면 위 태그가 어떤 역할을 하는지 알려면 찾아가야 하는 단점도 존재한다.
또한 Styled-Components를 사용한다면 CSS에 props를 전달할 수 있으며, CSS in JS의 대표적인 라이브러리로써 현재 많은 인기를 누리고 있다.
그렇다면 Styled-Components를 통해서 코드를 재구성해보자
const Wrapper = styled.div`
display: flex;
`;
const BoxOne = styled.div`
background-color: tomato;
width:200px;
height:200px;
`;
const BoxTwo = styled.div`
background-color: teal;
width: 200px;
height: 200px;
`;
const Text = styled.span`
font-size:35px;
color:white;
font-weight: 600;
`
function App() {
return (
<Wrapper>
<BoxOne>
<Text>Hi</Text>
</BoxOne>
<BoxTwo/>
</Wrapper>
);
}
Styled-components를 이용해 새로운 컴포넌트를 정의하였고, 이를 함수형 컴포넌트에서 사용했다. 코드가 한결 간단해졌고 직관적으로 컴포넌트 이름을 지정해줌으로써 해당 컴포넌트가 어떤 역할을 하는지 알 수 있게 된다. 또한 CSS를 컴포넌트 내부에 넣어줌으로써 CSS가 중복되지 않게 만들어준다.
터미널을 열고 아래 명령어를 입력해준다.
npm i styled-components
yarn add styled-components
npm을 통한 설치 시 위 명령어를, yarn을 이용할 시 아래 명령어를 입력한다.
설치가 완료되었다면 import를 통해서 컴포넌트를 만들 준비를 한다.
import styled from "styled-components";
Styled-Components를 이용하여 컴포넌트를 만드는 일은 생각보다 간편하다.
컴포넌트의 이름으로 변수를 하나 선언하고, styled 키워드에 사용할 html태그명을 붙인 뒤 백틱 ( 숫자 1 왼쪽에 있는 키 )을 열고 그 안에 CSS를 선언한다.
const Wrapper = styled.div`
내부 CSS 작성~~
`;
그렇다면 Styled-Components의 강력한 기능중에 하나인 props 전달해서 사용하는 방법을 살펴보자. 위에 작성된 코드를 살펴보면 Box컴포넌트의 CSS가 80% 일치하는걸 확인할 수 있다. BoxOne과 BoxTwo가 다른건 배경 색상 밖에 없다.
그럼 위 컴포넌트를 배경색상만 전달받고 통일할 수 있는 방법이 있지 않을까?
props를 통해 위 문제를 해결해보자!
const Wrapper = styled.div`
display: flex;
`;
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width:200px;
height:200px;
`;
const Text = styled.span`
font-size:35px;
color:white;
font-weight: 600;
`
function App() {
return (
<Wrapper>
<Box bgColor="tomato">
<Text>Hi</Text>
</Box>
<Box bgColor="teal"/>
</Wrapper>
);
}
코드를 살펴보면 Box 컴포넌트로 통합을 하였고 컴포넌트에 props을 전달 (bgColor)을 통해서 배경 색상을 지정해주고 있다. props를 통해서 코드의 중복을 제거하고 컴포넌트를 재사용 가능하게 만들어주고 있다.
그렇다면 이번엔 컴포넌트를 확장해보도록 하자.
Box컴포넌트의 CSS를 그대로 사용하며 추가적인 스타일을 갖는 다른 컴포넌트를 생성하려면 어떻게 해야할까?
위 코드에서 컴포넌트를 만들때 " styled.HTML태그 " 이런식으로 만들었다.
컴포넌트를 확장하고잘 할 때는 " styled(해당컴포넌트) " 이런식으로 만들어준다.
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width:200px;
height:200px;
`;
const Circle = styled(Box)`
border-radius: 100px;
`;
function App() {
return (
<Wrapper>
<Box bgColor="tomato">
<Text>Hi</Text>
</Box>
<Circle bgColor="blue"/>
</Wrapper>
);
}
Box 컴포넌트를 확장해서 Circle이라는 새로운 컴포넌트를 만들었다.
CSS를 작성하지 않았지만 컴포넌트를 확장하였고, border-radius 까지 잘 먹힌 모습을 확인할 수 있다.
말이 조금 복잡하다.
이미 만들어진 컴포넌트는 유지하고 싶지만 해당 컴포넌트가 button 태그가 아닌 a 태그였으면 좋겠다. 이를 어떻게 해결하면 좋을까?
바로 'as' attrs를 활용하면 된다!
const Btn = styled.button`
color:blue;
`;
function App() {
return (
<Wrapper>
<Btn>Hi</Btn>
<Btn>Component</Btn>
</Wrapper>
);
}
간단한 코드이다. Component 라는 텍스트를 가진 Btn 을 a 태그로 교체하고 싶다. as 를 이용해 변환해보자.
function App() {
return (
<Wrapper>
<Btn>Hi</Btn>
<Btn as="a">Component</Btn>
</Wrapper>
);
}
콘솔창을 통해 확인하니 a 태그로 변한 모습을 확인할 수 있다.
컴포넌트 안에 구성되어있는 자식 컴포넌트를 선택할 수 있는 방법은 없을까?
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width:200px;
height:200px;
`;
function App() {
return (
<Wrapper>
<Box>
<span>hi</span>
</Box>
</Wrapper>
);
}
Box 컴포넌트 안에 있는 span 태그를 지정해 스타일링을 하고싶다.
별도의 컴포넌트를 생성하지 않아도 선택자를 활용해 가능하다.
const Box = styled.div`
background-color: ${(props) => props.bgColor};
width:200px;
height:200px;
span {
color:white;
font-size:35px;
&:hover {
color:tomato;
}
}
`;
위 코드와 같이 해당 컴포넌트에서 하위 태그를 활용해 스타일을 지정해줄 수 있다.
&:hover 선택자를 통해서 span태그의 hover 효과를 입혀줄 수 도 있다.
여기서 &은 ^로도 사용할 수 있는데 이는 자기 자신을 말한다. (여기서는 span)
오늘 포스팅에서는 Styled-components에 대해서 알아봤다.
이를 통해서 직관적이고 가독성 좋은 코드를 한번 작성해보도록 해야겠다.