BEM: Block, Elment, Modifier
React에서 컴포넌트별로 스코핑이 되지 않기 때문에 BEM 방법론을 채택하기도 함
$ npm i sass
import './App.scss'
import styles from './App.modules.css'
styles
가 자동으로 선택자에 해시값을 추가해서 맵핑function App()
의 return 값 수정<div className={styles["App"]}></div> ...
전역적으로 오염되지 않은 스코프를 가짐
// Button.jsx
import styles from './Button.module.css'
const Button = (props) => <button className={styles['button']} {...props} />
export default Button
// Button.module.css
.button {
background: transparent;
border-radius: 3px;
border: 2px solid palevioletred;
margin: 0 1em;
padding: 0.25em 1em;
font-size: 20px;
cursor: pointer;
}
// Button.module.css
import React from 'react'
import styles from './Button.module.css'
// const Button = (props) => <button className={styles['button']} {...props} />
class Button extends React.Component {
state = {
loading: false,
}
render() {
return (
<button
onClick={this.startLoading}
className={
this.state.loading
? `${styles['button']} ${styles['loading']}`
: styles['button']
}
{...this.props}
/>
)
}
startLoading = () => {
this.setState({
loading: true,
})
setTimeout(() => {
this.setState({
loading: false,
})
}, 1000)
}
}
export default Button
classnames test
import classNames from 'classnames' console.log(classNames('foo', 'bar')) console.log(classNames('foo', 'bar', 'baz')) console.log(classNames({ foo: true }, { bar: false })) console.log( classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''), ) console.log(classNames(styles['button'], styles['loading']))
$ npm i classnames
import React from 'react'
import styles from './Button.module.css'
import classNames from 'classnames/bind' // bind 추가
const cx = classNames.bind(styles)
console.log(cx('button', 'loading'))
// const Button = (props) => <button className={styles['button']} {...props} />
class Button extends React.Component {
state = {
loading: false,
}
render() {
const { loading } = this.state
return (
<button
onClick={this.startLoading}
className={cx('button', { loading })}
{...this.props}
/>
)
}
startLoading = () => {
this.setState({
loading: true,
})
setTimeout(() => {
this.setState({
loading: false,
})
}, 1000)
}
}
export default Button
$ npm i styled-components
// StyledButton.jsx
import styled from 'styled-components'
const StyledButton = styled.button`
background: transparent;
border-radius: 3px;
border: 2px solid palevioletred;
margin: 0 1em;
padding: 0.25em 1em;
font-size: 20px;
cursor: pointer;
`
export default StyledButton
// 사용
import StyledButton from '../components/StyledButton'
<StyledButton>스타일버튼</StyledButton>
import Button from '../components/Button.jsx'
import StyledButton from '../components/StyledButton'
import StyledA from '../components/StyledA'
import styled, { createGlobalStyle } from 'styled-components'
const PrimaryStyledButton = styled(StyledButton)`
background: palevioletred;
color: white;
`
const UppercaseButton = (props) => (
<button {...props} children={props.children.toUpperCase()} />
)
const MyButton = (props) => (
// <button {...props} children={`MyButton ${props.children}`} />
<button className={props.className} children={`MyButton ${props.children}`} />
)
const StyledMyButton = styled(MyButton)`
background: transparent;
border-radius: 3px;
border: 2px solid ${(props) => props.color || 'palevioletred'};
color: ${(props) => props.color || 'palevioletred'};
margin: 0 1em;
padding: 0.25em 1em;
font-size: 20px;
cursor: pointer;
:hover {
border: 2px solid red;
font-size: 25px;
}
::before {
content: '@';
}
`
const GlobalStyle = createGlobalStyle`
button {
color: yellow;
}
`
export default function Home() {
return (
<div>
<GlobalStyle />
<h1>HOME</h1>
<Button>BTN</Button>
<StyledButton>스타일버튼</StyledButton>
<StyledButton primary>스타일버튼</StyledButton>
<PrimaryStyledButton>스타일버튼</PrimaryStyledButton>
<StyledButton as="a" href="/profile">
a버튼
</StyledButton>
<StyledButton as={UppercaseButton}>button</StyledButton>
<StyledMyButton>button</StyledMyButton>
<StyledMyButton color="green">button</StyledMyButton>
<StyledA href="https://google.com">구글로</StyledA>
</div>
)
}
// StyledA.jsx
import styled from 'styled-components'
const StyledA = styled.a.attrs((props) => ({
target: '_BLANK',
}))`
color: ${(props) => props.color};
`
export default StyledA
$ npm i react-shadow
$ npm i antd
// index.js
import 'antd/dist/antd.css'