styled-components란?
컴포넌트 스타일링 기법 중 하나로 class 이름을 지정하지 않아도 된다는 이점이 있다. 또한 컴포넌트에 스타일을 직접 적기 때문에 생성과 수정이 쉽고 직관적이다.
yarn add styled-components
이전에 설치했던 프로젝트와 달리 sytled-components는 나의 리액트 프로젝트 안에 패키지를 설치한다. 그래서 경로를 반드시 내가 설치하려는 프로젝트 안으로 설정해야 한다. package.json > "dependencies" 안에 프로젝트에 쓰이는 모든 패키지가 기록되기 때문이다.
import styled from "styled-components";
const MyStyled = styled.div`
width: 50vw;
height: 150px;
background: skyblue;
`;
2-Ⅰ에서 styled
를 import 했기 때문에 styled
이라는 객체를 만들어야 한다. 객체 안에는 css와 같은 방법으로 style을 주면 된다.
render() {
return (
<div className="App">
<MyStyled/>
</div>
);
}
선언한 객체를 render
안에 넣으면 적용 완료.
<MyStyled bg_color={"red"}/>
bg_color라는 이름의 props를 주었다. style-components 역시 컴포넌트이기 때문에 props를 줄 수 있다.
const MyStyled = styled.div`
width: 50vw;
height: 150px;
background-color: ${(props) => (props.bg_color)};
`;
props로 받아온 데이터 중 bg_color를 꺼낸 모습이다.
backtick(`)
안에서 props로 받아온 데이터를 활용할 땐 ${자바스크립트}
를 사용한다.
return
과 마찬가지로 삼항연산자와 변수는 사용 가능하나 if문과 for문은 쓸 수 없다.
중괄호 함수 {}
${(props) => { return props.bg_color; }}
화살표 함수 =>
${(props) => (props.bg_color)
중괄호{} 공식을 축약하면 화살표 함수가 된다.
삼항연산자
<MyStyled bg_color={"true"}/>
${(props) => (props.bg_color? "blue" : "green")};
삼항연산자를 활용하면 다음과 같은 응용도 가능하다.
SCSS 문법이란?
CSS를 보다 효율적이고 편리하게 사용하기 위해 만들어진 언어. CSS와 CSS의 확장문법인 SASS의 중간쯤이라고 생각하면 된다.
예시
- html
<MyStyled> <div> <p>hello, world!</p> </div> </MyStyled>
- CSS
.MyStyled { margin: auto; } .MyStyled > div { width: 50vw; height: 150px; background: skyblue; } .MyStyled > div > p { color: white; } .MyStyled > div > p:hover { color: yellow; }
.MyStyled {
margin: auto;
div {
width: 50vw;
height: 150px;
background: skyblue;
p {
color: white;
&:hover: { color: yellow; }
}
}
}
예시를 SCSS 문법으로 치환했다. 반복적인 부모 클래스를 일일이 적어줄 필요가 없기 때문에 경제적이고, html과 유사한 구조를 갖고 있어서 직관적이다. 이를 Nesting이라고 한다. 가상선택자를 사용할 땐 &
를 붙인다. &
는 나 자신을 지칭한다.
지난 시간에 만든 버킷리스트의 style을 css에서 styled-components로 바꿔보자.
App.js
render() { return ( <div className="App"> <Container> <Title >내 버킷리스트</Title> <Line/> <BucketList list={this.state.list} /> </Container> </div> ); }
const Container = styled.div` max-width: 350px; min-height: 80vh; background-color: #fff; padding: 16px; margin: 20px auto; border-radius: 5px; border: 1px solid #ddd; `; const Title = styled.h1` color: slateblue; text-align: center; `; const Line = styled.hr` margin: 16px 0px; border: 1px dotted #ddd; `;
BucketList.js
import React from 'react'; import styled from "styled-components"; const my_lists = list; return ( <div> { my_lists.map((list, index) => { console.log(list); return ( <ItemStyle key={index}> {list} </ItemStyle > ); }) } </div> ); } const ItemStyle = styled.div` padding: 26px; margin: 8px; background-color: rgb(250, 247, 216); `; export default BucketList;
class App extends React.Component { constructor(props) { super(props); this.state = { list: ["Eternals", "First Cow", "Seberg", "French Dispatch"], } } render() { return ( <Back> <MyStyled> <div> <h2>개봉예정작</h2> <hr/> <ListItem list = {this.state.list}/> </div> </MyStyled> </Back> ); }
const Back = styled.div` background-color: #eee; height: 100vh; width: 100vw; display: flex; `; const MyStyled = styled.div` height: 80vh; background-color: #fff; width: 50vw; max-width: 350px; margin: auto; padding: 16px; border: 1px solid #ddd; border-radius: 3px; h2 { color: rgb(146, 105, 184); text-align: center; } hr { margin: 16px 8px; } `; const ListItem = styled.div ` padding: 26px; margin: 8px; background-color: rgb(250, 247, 216); `;
정답에서는 styled.components를 최대한 많이 사용하기 위해 컴포넌트에 객체를 지정했지만 나는 Nesting을 사용해서 코드를 간소화하였다. 여기까지는 방식의 차이인데 props로 받아온 <ListItem list = {this.state.list}/>
이 부분이 틀렸다. BucketList.js로 데이터를 보내주고 있는 걸 깜빡한 것이다. 그래서 <ListItem list = {this.state.list}/>
은 App.js가 아니라 BucketList.js에서 style-components를 사용해야 한다. BucketList.js에서도 App.js에서 했던 것과 마찬가지로 style-components를 import 한 뒤 const를 사용하면 된다. 오답대로 작성하면 브라우저에서는 props의 데이터 없이 style만 덩그러니 출력된다.