위와 같은 이유로 React에서는 스타일을 설정할 때 SCSS, CSS module 혹은 styled-components를 활용한다.
//Post 컴포넌트
import '../styles/Post.scss'
function Post({ bgColor, fontSize, ...rest}) { //SCSS에서 사용할 클래스 이름
return (//...rest는 bgColor나 fontSize 외에도 적용할 다른 스타일 또는 props
<p className={ `Post ${ bgColor } ${ fontSize } ${ ...rest }` }>
포스트
</p>
)
}
export default Post
css 모듈은 css 클래스의 범위를 별도의 컴포넌트로 지정할 수 있는 CSS 파일 구조이다. CSS 모듈을 사용하면 각 css 클래스에 고유한 이름으로 지정되어 이름이 충돌할 위험이 없다.
css 모듈을 사용하려면 css-loader가 필요하다. 그러나 이번에 배울 때 쓰는 vite로 React 프로젝트를 생성하면 이미 설치되어있다. $ yarn create vite --template react
/* ../styles/Post.module.css */
.Post {
background-color: blue;
color: white;
font-size: 2rem;
}
.small {
width: 200px;
height: 120px;
}
//Post 컴포넌트
...
import style from '../styles/Post.module.css'
//개발자도구에서 확인하면 class명이 고유값으로 적용된 것을 확인할 수 있다.
function Post() {
return (
<p className={ `${ style.Post } ${ style.small }` }>
포스트
</p>
)
}
export default Post
$ yarn add styled-components
styled-components는 스타일이 적용된 컴포넌트를 만들 수 있게 해주는 모듈이며, 테마 설정, 글로벌 스타일 생성, props 활용과 같은 기능을 제공한다.
//../components/Post/style.js
import styled from 'styled-components'
export const Post = styled.Post`
background-color: blue;
color: white;
font-size: 2rem;
border: 1px solid ${(props) => props.borderColor
|| '#000'};
`
...
//../components/Post/index.js
import * as S from './style'
function Post() {
return (
<S.Post borderColor="#3D3D3D">
<p>포스트</p>
</S.Post>
)
}
export default Post
themeprovider는 전역의 공통된 스타일 값을 쓸 수 있도록 해주며, 이는 스타일을 단순화하고 구성 요소 간에 일관성을 높인다.
styled-compoenets
//../styles/theme.js
const palette = {
orange: '#FFA500',
black: '#000',
}
const theme = {
palette,
}
export default theme
위와 같이 theme을 설정할 theme.js를 만들고, 아래와 같이 <ThemeProvider> 태그로 감싸준다.
import { ThemeProvider } from 'styled-components'
import theme from './styles/theme'
import Post from './components/Post'
function App() {
return (
<ThemeProvider theme={theme}>
<Post />
</ThemeProvider>
)
}
export default App
이를 통해 Post 컴포넌트의 styled-components에 불러와서 공통된 스타일을 적용할 수 있다.
//../components/Post/style.js
import styled from 'styled-components'
export const Post = styled.Post`
background-color: blue;
color: white;
font-size: 2rem;
border: 1px solid ${(props) => props.theme.palette.orange
|| '#000'};
`
이렇게 되면 Post/index.jsx에서 props를 전달할 필요가 없어지므로 없앨 수 있다.
...
//../components/Post/index.js
import * as S from './style'
function Post() {
return (
<S.Post>
<p>포스트</p>
</S.Post>
)
}
export default Post
또한 theme.js에서 scss의 @mixin/@include 기능처럼 넣어줄 수 있다.
//../styles/theme.js
const palette = {
orange: '#FFA500',
black: '#000',
}
const common = {
flexCenter: `
display: flex;
justify-content: center;
align-items: center;
`,
}
const theme = {
palette,
common,
}
export default theme