styled-components
설치
npm i styled-components
import
import styled from "styled-components";
고정 스타일링
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: gray;
background: white;
`;
function Button({ children }) {
return <StyledButton>{children}</StyledButton>;
}
가변 스타일링
Styled Components는 React 컴포넌트에 넘어온 props에 따라 다른 스타일을 적용하는 기능을 제공
버튼의 글자색과 배경색을 props따라 바뀌도록 위에서 작성한 예제 코드를 변경해보겠습니다. 자바스크립트의 ||연산자를 사용하여 props이 넘어오지 않은 경우, 기존에 정의한 기본 색상이 그대로 유지되도록 합니다.
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: ${(props) => props.color || "gray"};
background: ${(props) => props.background || "white"};
`;
function Button({ children, color, background }) {
return (
<StyledButton color={color} background={background} Î>
{children}
</StyledButton>
);
}
import Button from "./Button";
<Button color="green" background="pink">
Green Button
</Button>;
가변 스타일링 2
prop에 따라 바꾸고 싶은 CSS 속성이 위와 같이 하나가 아니라 여러 개일 경우가 있습니다. 이럴 경우, Styled Components에서 제공하는 css 함수를 사용해서 여러 개의 CSS 속성을 묶어서 정의할 수 있습니다.
import
import styled, { css } from "styled-components";
예를 들어, primary prop이 넘어온 경우, 글자색을 흰색, 배경색과 경계색은 남색으로 변경하고 싶다면 다음과 같이 예제 코드를 수정할 수 있습니다. 이번에는 자바스크립트의 && 연산자를 사용해서, primary prop이 존재하는 경우에만 css로 정의된 스타일이 적용되도록 하였습니다.
import React from "react";
import styled, { css } from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
${(props) =>
props.primary &&
css`
color: white;
background: navy;
border-color: navy;
`}
`;
function Button({ children, name }) {
return <StyledButton {name}>{children}</StyledButton>;
}
참고로 넘겨야할 prop 값이 많아질 경우, 위와 같이 ...props 구문을 사용해서 children 외에 모든 prop을 간편하게 전달할 수 있습니다.
자, 이제 다음과 같이 하나의 prop 만으로 여러가지 CSS 속성이 한 번에 적용된 버튼을 얻을 수 있습니다.
import Button from "./Button";
<Button primary>Primary Button</Button>;
ThemeProvider
참고 블로그 : https://wonit.tistory.com/366 ThemeProvider 가 바로 context를 사용해서 모든 리액트 컴포넌트에게 theme 속성을 전달하는 역할을 수행한다.
import React from "react";
import { ThemeProvider } from "styled-components";
const theme = {
// ... 사용자 정의 theme code
}
const Home = () => {
return (
<ThemeProvider theme={theme}>
<Header />
<Sidebar />
<HeroSection />
<Footer />
</ThemeProvider>
);
}
Home 컴포넌트에서 최상단의 태그가 <ThemeProvider> 이므로 하위 자식의 모든 컴포넌트는 <ThemeProvider> 의 props로 넘어가는 theme 값을 사용할 수 있게되는 것
theme/theme.js
const theme = {
mainColor: "#3498db",
dangerColor: "#e74c3c",
successColor: "#2ecc71",
};
export default theme;
App.js
import styled, { ThemeProvider } from "styled-components";
import React, { useState, useReducer } from "react";
import theme from "./theme/theme.js";
const Card = styled.div`
border-radius: 30px;
padding: 25px 15px;
background-color: ${(props) => props.theme.successColor};
`;
function App(props) {
return (
<ThemeProvider theme={theme}>
<Card />
</ThemeProvider>
);
}
export default App;
실제 응용 코드 예시
예를 들어 display:flex나 h1의 font-size, color를 ThemeProvider를 사용해서 공통 작업을 한다고 해보자.
import styled from "styled-components";
// 반응형 디자인을 위한 픽셀 컨버팅 함수const pixelToRem = (size) => `${size / 16}rem`;
// font size를 객체로 반환해주자.const fontSizes = {
title: pixelToRem(60),
subtitle: pixelToRem(30),
paragraph: pixelToRem(18),
};
// 자주 사용하는 색을 객체로 만들자.const colors = {
black: "#000000",
grey: "#999999",
green: "#3cb46e",
blue: "#000080",
};
// 자주 사용하는 스타일 속성을 theme으로 만들어보자.const common = {
flexCenter: `
display: flex;
justify-contents: center;
align-items: center;
`,
flexCenterColumn: `
display: flex;
flex-direction: column;
justify-contents: center;
align-items: center;
`,
};
// theme 객체에 감싸서 반환한다.const theme = {
fontSizes,
colors,
common,
};
export default theme;
위에 파일에 나온 내용은 다음과 같다.
- font-size 통일
- color 통일
- display flex center 자동 생성기
그리고 App.js 파일에서 우리가 만든 theme들을 사용해보자.
import React from "react";
import styled, { ThemeProvider } from "styled-components";
import theme from "./theme";
const Container = styled.div`
width: 100vw;
height: 100vh;
${({ theme }) => theme.common.flexCenterColumn};
`;
const Title = styled.h1`
font-size: ${({ theme }) => theme.fontSizes.title};
color: ${({ theme }) => theme.colors.grey};
`;
const Subtitle = styled.h2`
font-size: ${({ theme }) => theme.fontSizes.subtitle};
color: ${({ theme }) => theme.colors.green};
`;
const Paragraph = styled.p`
font-size: ${({ theme }) => theme.fontSizes.Paragraph};
color: ${({ theme }) => theme.colors.blue};
`;
const App = () => {
return (
<div><ThemeProvider theme={theme}><Container><Title>Hello</Title><Subtitle>Welcome to styled-component's world</Subtitle><Paragraph>ThemeProvider에 대해서 배워볼까요?</Paragraph></Container></ThemeProvider></div>
);
};
export default ThemeProviderPrac;
styled-components에서 props로 넘오는 객체 혹은 값들을 사용하려면 ${} 리터럴로 언패킹 해주면 된다!
createGlobalStyle
전역적으로 무언가를 적용하고 싶을때 사용
const GlobalStyle = createGlobalStyle`
body{
background: #e9ecef;
}
`;
function App() {
return (
<~~~~>
<GlobalStyle />
<~~~>
<~~~ />
<~~~ />
<~~~ />
</~~~>
</~~~>
);
}
App.js에서 다음같이 파일을 만들어주고, 위 코드 처럼, 가장 밖에서 감싸고 있는 태그 안에 적어주기만 하면 배경색이 #e9ecef가 됨
'Front-end > React' 카테고리의 다른 글
useRef (0) | 2022.03.14 |
---|---|
Custom hook (0) | 2022.03.14 |
[React] useCallback (0) | 2022.03.09 |
[React] useMemo 원시타입/객체 타입 (0) | 2022.03.09 |
Redux 란 ? Redux Setting Up - 1 (0) | 2022.03.07 |