[FE_Bootcamp] 46일차_Component Driven Development
1. CDD
우리는 컴포넌트식 구성을 통해 HTML과 JS를 동시에 제어할 수 있다는 것을 배웠다.
하지만, CSS는 여전히 컴포넌트, 더 나아가 JS 파일 바깥에서 따로 받아와야 한다.
그리고 이 CSS파일은 따로 컴포넌트별로 나누어지지 않아 있기 때문에 우리가 원하는 컴포넌트나 엘리먼트에 스타일을 적용하기 위해서는 일일히 찾아줘야 하는 불편함도 있다.
당장 이 블로그를 쓰는 것만 해도, CSS 파일이 무려 2100줄 이상 필요하다.
과연 이 CSS 파일에서 내가 원하는 컴포넌트나 엘리먼트를 쉽게 찾을 수 있을까?
또한, 컴포넌트를 공유하는 경우 스타일을 적용하기 위해서는 다시 CSS파일을 만들어 import 해주어야 한다.
이러한 문제점을 해결하기 위해 등장한 개발 방법이 바로 Component Driven Development (CDD) 이다.
CDD는 부품 단위로 UI 컴포넌트를 만들어 조립하는 방식을 사용하여 페이지를 만들 수 있게 한다.
2. Styled-Component
웹 페이지가 애플리케이션화되며, 컴포넌트의 기능이 더욱 중요해졌다.
하지만 CSS는 컴포넌트 기반의 개발 방식에 맞추어 진화된 적이 없었다.
CSS를 컴포넌트 영역으로 불러들이기 위해서 탄생한 것이 CSS-in-JS이다.
CSS-in-JS에는 대표적으로 Styled-Component가 있는데, Styled-Component는 기능적(Functional) 혹은 상태를 가진 컴포넌트들로부터 UI를 완전히 분리해 사용할 수 있는 아주 단순한 패턴을 제공한다.
Styled-Components같은 CSS in JS 라이브러리를 사용하면 CSS도 쉽게 Javascript 안에 넣어줄 수 있으므로, HTML + JS + CSS까지 묶어서 하나의 JS파일 안에서 컴포넌트 단위의 개발이 가능하다.
지금부터는 Styled-Component를 이용해 컴포넌트를 만들고, 스타일을 적용시켜 보도록 하자.
A. 컴포넌트 만들기
styled-component를 사용하기 위해서는 npm 설치 후 import를 통해 불러와야 한다.
파이썬에서 라이브러리를 import할때, 이름을 지정해줄 수 있듯 styled-component도 따로 이름을 붙여줄 수 있다.
import styled from "styled-components"
이제 'styled'를 통해 styled-component를 사용할 수 있다.
간단한 컴포넌트를 만들어보자.
const '컴포넌트 이름' = styled.태그`
css 속성 : 속성값;
css 속성 : 속성값;
`
Styled Components는 ES6의 Templete Literals 문법을 사용하기 때문에. 따옴표가 아닌 백 틱(`)을 사용한다.
컴포넌트를 선언하고, styled.태그로 원하는 컴포넌트를 만든 뒤 백 틱 안에 기존에 CSS를 작성하던 문법과 똑같이 스타일 속성을 작성해준다.
이렇게 만든 컴포넌트를 React 컴포넌트를 사용하듯 리턴문 안에 작성해 주면 스타일이 적용된 컴포넌트가 렌더링된다.
import styled from 'styled-components'
function App() {
const RedButton = styled.button`
color:white;
background-color: red;
border: 2px black solid;
height : 50px;
width : 100px;
margin : 10px;
`
const BlueButton = styled.button`
color:white;
background-color: blue;
border: 2px black solid;
height : 50px;
width : 100px;
margin : 10px;
`
const GreenButton = styled.button`
color:white;
background-color: green;
border: 2px black solid;
height : 50px;
width : 100px;
margin : 10px;
`
return (
<div>
<RedButton>빨간 버튼 </RedButton>
<BlueButton>파랑 버튼 </BlueButton>
<GreenButton>초록 버튼 </GreenButton>
</div>
)
}
export default App;
B. 이미 만들어진 컴포넌트 재활용하기
Styled Components는 만들어져있는 컴포넌트를 재사용할 수 있다는 장점이 있다.
만약 이미 만들어진 컴포넌트에 다른 스타일을 추가하거나, 스타일을 변경하고싶다면 컴포넌트를 불러와 재사용하면 된다.
const '컴포넌트 이름' = styled(재사용할 컴포넌트)`
css 속성 : 속성값;
css 속성 : 속성값;
`
위에서 만든 RedButton을 불러와 새로운 컴포넌트를 만들어보자
import styled from 'styled-components'
function App() {
const RedButton = styled.button`
color:white;
background-color: red;
border: 2px black solid;
height : 50px;
width : 100px;
margin : 10px;
`
const RedDottedButton = styled(RedButton)`
border: 5px blue dotted;
`
const RedShadowedButton = styled(RedButton)`
box-shadow: 5px 5px 10px black;
`
const BlueButton = styled(RedButton)`
background-color: blue;
`
return (
<div>
<RedButton>빨간 버튼 </RedButton>
<RedDottedButton>빨간 점선 버튼</RedDottedButton>
<RedShadowedButton>빨간 그림자 버튼</RedShadowedButton>
<BlueButton>파랑 버튼 </BlueButton>
</div>
)
}
export default App;
RedButton은 Styled Components로 만들고, 이 RedButton을 이용해 새로운 컴포넌트 3개를 만들어 주었다
- RedDottedButton : RedButton의 border 요소를 수정
- RedShadowedButton : RedButton에 box-shadow 추가
- BlueButton : RedButton의 background-color 요소를 수정
위와 같이 컴포넌트를 불러오면 스타일 수정, 추가가 가능하다.
C. props로 조건부 렌더링
Styled Components 역시 일반 리액트 컴포넌트처럼 props를 사용해 값을 전달할 수 있고, 전달받은 props 값에 따라 조건부 렌더링이 가능하다.
Styled Components는 리터럴 문법 (${})를 이용해 JS 문법을 이용할 수 있다. props는 이 리터럴 문법 안에서, props를 인자로 받아오는 함수를 작성하여 사용할 수 있다.
이번에는 props 값에 따라 색상이 변하게 하는 기능을 구현해보자.
import styled from 'styled-components'
function App() {
const Button = styled.button`
color:white;
border: 2px black solid;
height : 50px;
width : 100px;
margin : 10px;
background-color: ${(props) => (props.color ? props.color : "black")};
`
return (
<div>
<Button color='red'>color 속성을 준 버튼</Button>
<Button>color 속성을 안준 버튼</Button>
</div>
)
}
export default App;
Button 컴포넌트 자체를 props라고 생각하면 편할 듯 하다.
props.color는 Button.color, 즉 Button 컴포넌트의 color 속성이라고 생각하면 될 것 같다.
다른 속성들은 그냥 선언했지만, 배경색만은 리터럴 문법을 이용해 조건에 따라 다르게 해주었다.
컴포넌트에 color라는 속성이 있으면, 배경색은 props.color(=color 속성 안에 담긴 색상)으로 설정하고
아니라면 그냥 black으로 설정해주기로 한다.
그리고 첫번째 버튼의 color 속성은 'red', 두번째 버튼은 color 속성을 부여해주지 않는다
과연 어떤 결과가 나올까??
첫번째 버튼의 background-color는 color 속성에 담겨있는 'red', 두번째 버튼은 color 속성이 없을때의 기본값인 black으로 설정된 것을 볼 수 있다.
D. 전역 스타일 설정
전역 스타일은 스타일을 따로 설정해주지 않은 컴포넌트들에게 공통적으로 적용되는 속성이다.
전역 스타일을 설정하기 위해서는 Styled Components에서 createGlobalStyle 함수를 불러와야 한다.
그리고, createGlobalStyle 함수를 사용해 CSS에서 스타일을 작성하듯 원하는 태그나 클래스, ID에 대한 스타일을 작성해주면 된다.
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
button {
color:white;
border: 2px black solid;
height : 50px;
width : 100px;
margin : 10px;
background-color: red;
}
`
그리고, 이 전역 스타일을 적용하려면 최상위 컴포넌트에 전역 스타일을 선언한 컴포넌트를 넣어주면 된다.
import styled from 'styled-components'
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
button {
color:white;
border: 2px black solid;
height : 50px;
width : 100px;
margin : 10px;
background-color: red;
}
`
function App() {
return (
<div>
<GlobalStyle/>
<button> 1번 버튼</button>
<button> 2번 버튼</button>
<button> 3번 버튼</button>
</div>
)
}
export default App;
앞으로 만들어지는 button 태그들에는 전부 같은 스타일이 적용될 것이다.
E. 의사 클래스 구현
Styled Components는 hover, focused 등의 다양한 의사 클래스 역시 구현 가능하다.
기존 CSS에서는, 원하는 태그나 클래스. ID 뒤에 ':'을 붙이고 의사 클래스를 구현해 주었지만, Styled Components에서는 스타일 안에 '&:의사 클래스'를 사용해 구현이 가능하다.
import styled from 'styled-components'
function App() {
const Button = styled.button`
color:white;
border: 2px black solid;
height : 50px;
width : 100px;
margin : 10px;
background-color: red;
&:hover{
background-color: blue;
}
`
return (
<div>
<Button>hover</Button>
</div>
)
}
export default App;
이 코드는 버튼에 hover되었을 때 배경색을 변경해주는 코드이다.
이처럼 &: 를 이용하면 다양한 의사 클래스 역시 구현이 가능하다.