리액트 컴포넌트를 외부 라이브러리 없이 CSS로 스타일링 하는 방법중 가장 대중적인 방법이 Styled Components를 사용하는 방법이다. 이번 포스팅에선 Styled Components를 알아볼까 한다.
CSS in JS
Styled Components는 CSS in JS의 개념으로 제작된 라이브러리이다. 스타일 정의를 보통 css 파일에다가 하지만 CSS in JS는 Javascript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법을 말하는 것이다.
고전 프론트엔드의 방식은 HTML, CSS, JS를 분리하여 개발하였지만 최근 개발 패러다임은 컴포넌트들을 분리하고, 각 컴포넌트들 안에 HTML, CSS, JS를 모두 때려 박는 방식이 사용되고 있다. Styled Component 또한 이러한 방식에 맞춰 CSS를 JS안에 쉽게 적용 할 수 있도록 도와주는 라이브러리이다.
Styled Component 사용 해 보기
npx create-react-app styled-components-example
cd styled-components-example
npm i styled-components
code .
npm start
- CRA로 만든 프로젝트 내에서 StyledButton 컴포넌트를 하나 생성해준 뒤 다음과 같이 작성 하였다.
import styled from 'styled-components'
const StyledButton = styled.button`
background: transparent;
border-radius: 5px;
border: 2px solid palevioletred;
color: palevioletred;
margin: 0 1em;
padding: 0.25em 1em;
font-size: 20px;
`; //템플릿 스트링 사이에 css를 넣는 방식이다.
export default StyledButton;
- JS에서 지원하는 Template string (``)을 이용하여 css를 넣는 방식이다.
- 하지만 String 형식으로 작성하면 IDE기능을 사용할 수 없다. (자동완성, 문법 오류)
- 플러그인으로 해결 가능함
Styled Component의 Props
App.js
import logo from "./logo.svg";
import "./App.css";
import StyledButton from "./components/StyledButton";
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<StyledButton>버튼</StyledButton>
<StyledButton primary>버튼</StyledButton>
</p>
</header>
</div>
);
}
export default App;
StyledComponent.jsx
import styled, { css } from 'styled-components'
const StyledButton = styled.button`
background: transparent;
border-radius: 5px;
border: 2px solid palevioletred;
color: palevioletred;
margin: 0 1em;
padding: 0.25em 1em;
font-size: 20px;
${props => props.primary && css`
background-color: palevioletred;
color: white;
`}
`; //템플릿 스트링 사이에 css를 넣는 방식이다.
export default StyledButton;
- 다음과 같이 작성하면, props를 받아와서 제작 할 수도 있다.
- 다른 기능을 가진 버튼에 적용해놓은 스타일을 먹이고 싶다면 이러한 방법또한 사용 가능하다.
import logo from "./logo.svg";
import "./App.css";
import StyledButton from "./components/StyledButton";
const UppercaseButton = (props) => <button {...props} children={props.children.toUpperCase()}/>;
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<StyledButton>버튼</StyledButton>
<StyledButton primary>버튼</StyledButton>
<StyledButton as ={UppercaseButton} href="/">button</StyledButton>
</p>
</header>
</div>
);
}
export default App;
- as 키워드를 사용하여 특정 기능을 하는 버튼의 컴포넌트 또한 가져올 수 있다.
- 다음과 같은 방식으로도 특정 기능을 하는 컴포넌트를 가져올 수 있다.
import logo from "./logo.svg";
import "./App.css";
import StyledButton from "./components/StyledButton";
import styled from "styled-components";
const MyButton = (props) => <button {...props} children={`MyButton ${props.children}`}/>;
const StyledMyButton = styled(MyButton)`
background: transparent;
border-radius: 5px;
border: 2px solid palevioletred;
color: palevioletred;
margin: 0 1em;
padding: 0.25em 1em;
font-size: 20px;
`;
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<StyledButton>버튼</StyledButton>
<StyledButton primary>버튼</StyledButton>
<StyledMyButton>button</StyledMyButton>
</p>
</header>
</div>
);
}
export default App;
- 여기서 중요한 점은 MyButton에서 props를 Spread Operator로 복사 해 오는데, className을 복사 해 온다는 점을 알아야 한다.
const MyButton = (props) => <button {...props} children={`MyButton ${props.children}`}/>;
const MyButton = (props) => <button className={props.className} children={`MyButton ${props.children}`}/>;
특정 값을 받아 props 인자로 처리하기
const StyledMyButton = styled(MyButton)`
background: transparent;
border-radius: 5px;
border: 2px solid ${((props) => props.color || "palevioletred")};
color: palevioletred;
margin: 0 1em;
padding: 0.25em 1em;
font-size: 20px;
`;
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<StyledButton>버튼</StyledButton>
<StyledButton primary>버튼</StyledButton>
<StyledMyButton color="green">button</StyledMyButton>
</p>
</header>
</div>
);
}
- 다음과 같은 방식으로 props 인자에 color가 들어왓을땐 그 색상으로 아닐 땐 기본 값인 pleviotred로 만들어 줄 수 있다.
전역적으로 스타일 주기
- 전역적으로 스타일을 줄 땐 그냥 css를 사용 하면 되지 않느냐? 라고 질문 한다면, 가능은 하다라고 말 할 수 있다.
- 하지만, Styled-Component 자체에서도 GlobalStyle을 지원 하고 있다.
import styled, { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
button{
color: yellow
}
`;
function App() {
return (
<div className="App">
<GlobalStyle /> //글로벌 스타일 컴포넌트 또한 렌더를 해줘야 한다.
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<StyledButton>버튼</StyledButton>
<StyledButton primary>버튼</StyledButton>
<StyledMyButton color="green">button</StyledMyButton>
</p>
</header>
</div>
);
}
export default App;
- GlobalStyle 컴포넌트도 렌더 해줘야 하기 때문에 App 다음으로 최상위에다가 작성을 해 주었다.
레퍼런스
'프론트엔드 개발 > React' 카테고리의 다른 글
[React] 기본 Hooks (0) | 2022.07.11 |
---|---|
[React] Higher Order Component (0) | 2022.07.11 |
[React] Router - JSX로 라우팅 이동하기 (0) | 2022.07.05 |
[React] Dynamic Routing (0) | 2022.07.05 |
[React] SPA Router (0) | 2022.07.05 |