react 에서 CSS 를 사용하는 방법에는 몇가지가 있다.
inline - style 속성 사용 (참고: https://reactjs.org/docs/dom-elements.html#style)
CSS classes are generally better for performance than inline styles. (CSS class 를 사용하는 것이 일반적으로 inline styles 를 사용하는 것보다 성능이 좋다.)
var divStyle = { color: 'white' , backgroudImage: 'url(' + imgUrl + ')' , WebkitTranstion: 'all' , // note the capital 'W' here msTransition: 'all' // 'ms' is the only lowercase vendor prefix }; ReactDOM.render(<div style={divStyle}>Hello World!</div>, mountNode); |
CSS 파일 사용 (참고: https://velopert.com/1555)
의존 모듈(css-loader, style-loader) 설치 및 webpack.config.js 에 loaders 추가 필요
.container { position: fixed; width: 100 %; height: 100 %; background-color: black; } .hello { color: white; position: fixed; top: 50 %; left: 50 %; transform: translate(- 50 %, - 50 %); font-size: 3rem; } |
import React from 'react' ; import styles from './App.css' ; export default class App extends React.Component { componentWillMount() { document.body.style.margin = 0 ; document.body.style.padding = 0 ; } render() { return ( <div className={styles.container}> <div className={styles.testing}> hello </div> </div> ); } } |
styled-components (참고: https://www.styled-components.com/)
CSS 파일을 사용할 경우, CSS 와 컴포넌트 파일이 떨어져있다보니 관리가 불편한 점이 있다. styled-components 는 컴포넌트를 생성할 때 스타일을 줄 수 있기때문에 CSS 파일을 따로 관리하지 않아도 된다는 장점이 있다.
const Button = styled.a` display: inline-block; border-radius: 3px; padding: 0 .5rem 0 ; margin: 0 .5rem 1rem; width: 11rem; background: transparent; color: white; border: 2px solid white; ${props => props.primary && css` background: white; color: palevioletred; `} ` |
styled-components
설치
npm install --save styled-components |
styled-components babel plugin 을 사용하는 것을 매우 추천한다. (필수 아님) 읽기 쉬운 클래스 이름, 서버 측 렌더링 호환성, 더 작은 번들 등과 같은 많은 이점을 제공한다.
npm install --save --dev babel-plugin-styled-components |
.babelrc 에 “styled-components” 플러그인을 추가한다.
{ "presets" : [ "env" , "react" ], "plugins" : [ "styled-components" ] } |
시작하기
styled-components 는 태그가 있는 템플릿 리터럴을 사용하여 컴포넌트의 스타일을 지정한다.
기존에 컴포넌트를 <h1> 태그를 사용하고 class 를 통해 스타일을 줬다면 styled-components 는 styled.h1 을 사용하고 `` 안에 CSS 를 작성하면 된다.
CSS 코드와의 비교
CSS 사용 코드
import styles from './styles.css' ; class Counter extends Component { state = { /* .. */ } increment = () => { /* ... */ } decrement = () => { /* ... */ } render() { return ( <div className={styles.counter}> <p className={styles.paragraph}>{ this .state.count}</p> <button className={styles.button} onClick={ this .increment}>+</button> <button className={styles.button} onClick={ this .decrement}>-</button> </div> ) } } |
styled-components 사용 코드
import styled from 'styled-components' ; const StyledCounter = styled.div` /* ... */ `; const Paragraph = styled.p` /* ... */ `; const Button = styled.button` /* ... */ `; class Counter extends Component { state = { /* ... */ } increment = () => { /* ... */ } decrement = () => { /* ... */ } render() { return ( <StyledCounter> <Paragraph>{ this .state.count}</Paragraph> <Button onClick={ this .increment}>+</Button> <Button onClick={ this .decrement}>-</Button> </StyledCounter> ) } } |
주의사항
render method 안에 styled component 를 만들지 말라.
// good
const StyledWrapper = styled.div` /* ... */ `; const Wrapper = ({ message }) => { return <StyledWrapper>{message}</StyledWrapper> }; |
// bad
const Wrapper = ({ message }) => { // WARNING: THIS IS VERY VERY BAD AND SLOW, DO NOT DO THIS!!! const StyledWrapper = styled.div` /* ... */ `; return <StyledWrapper>{message}</StyledWrapper> }; |
컴포넌트의 render 함수 안에 styled-component 는 공식 사이트에서도 반대하는 아주 나쁜 코드방식이다. 이렇게 작성할 경우 Wrapper 컴포넌트가 렌더링이 될 때마다 StyledWrapper 를 생성하기 때문이다. (원래 render 함수에서 함수 생성 및 함수 바인딩도 하는 코드 방식도 안좋다.)
props 사용
const Button = styled.button` background: ${props => props.primary ? "palevioletred" : "white" }; color: ${props => props.primary ? "white" : "palevioletred" }; font-size: 1em; margin: 1em; padding: 0 .25em 1em; border: 2px solid palevioletred; border-radius: 3px; `; ... render( <div> <Button>Normal</Button> <Button parimary>Primary<Button> </div> ); |
외부 라이브러리 사용시 방법
// react-router-dom 의 Link 일 경우. const Link = ({ className, children }) => { <a className={className}> {children} </a> }; const StyledList = styled(Link)` color: palevioletred; font-weight: bold; `; render( <div> <Link>Unstyled, boring Link</Link> <br /> <StyledLink>Styled, exiting Link</StyledLink> </div> ); |
스타일 상속
const Button = styled.button` color: palevioletred; font-size: 1em; margin: 1em; padding: 0 .25em 1em; border: 2px solid palevioletred; border-radius: 3px; `; const TomatoButton = styled(Button)` color: tomato; border-color: tomato; `; render( <div> <Button>Noraml Button</Button> <TomatoButton>Tomato Button</TomatoButton> </div> ); |
attribute
const Input = styled.input.attrs({ type: 'password' , margin: props => props.size || '1em' , padding: props => props.size || '1em' })` color: palevioletred; font-size: 1em; border: 2px solid palevioletred; border-radius: 3px; margin: ${props => props.marin}; pading: ${props => props.padding}; `; render ( <div> <Input placeholder= "A small text input" size= "1em" /> <br /> <Input placeholder= "A bigger text input" size= "2em" /> </div> ); |
Animations
const rotate360 = keyframes` from { transform: rotate(0deg); } to { transform: rotate(360deg); } }; const Rotate = styled.div` display: inline-block; animation: ${rotate360} 2s linear infinite; padding: 2rem 1rem; font-size: 1 .2rem; `; render( <Rotate>test</Rotate> ) |
더 자세한 내용은 공식 사이트를 참고하시기 바랍니다. https://www.styled-components.com/docs/advanced
'JavaScript > React' 카테고리의 다른 글
[React] Stateless Component (0) | 2018.11.30 |
---|---|
[ReactJS] React private route 로그인 권한 (0) | 2018.10.16 |
React 로 TDD 쵸큼 맛보기 (0) | 2018.07.20 |
[ReactJS] scroll to top (0) | 2017.07.31 |
[React] 속도 향상 (0) | 2017.07.25 |
댓글