React Component Styling

protect-me·2021년 9월 16일
0

⚛️ React

목록 보기
5/7
post-thumbnail

참고 https://slides.com/woongjae/react2021

1. Style Loaders

BEM: Block, Elment, Modifier
React에서 컴포넌트별로 스코핑이 되지 않기 때문에 BEM 방법론을 채택하기도 함

2. SCSS 적용

  1. App.scss 파일 생성 및 작성
  2. $ npm i sass
  3. App.js
    import './App.scss'

3. CSS Modules

  1. App.js
    import styles from './App.modules.css'
  2. src > App.css 생성 및 작성
  3. styles가 자동으로 선택자에 해시값을 추가해서 맵핑
  4. function App()의 return 값 수정
    <div className={styles["App"]}></div> ...

    전역적으로 오염되지 않은 스코프를 가짐

Button 기본

// 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 로딩 추가

// 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

Button 로딩 추가 - classnames 추가

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

4. Styled Components

  • 별도 라이브러리를 통해 스타일링을 좀더 손쉽게 가능
  • $ 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

5. React Shadow

  • $ npm i react-shadow
  • 컴포넌트마다 격리시켜 style을 독립적으로 적용시킬 수 있음

6. Ant Design

// index.js
import 'antd/dist/antd.css'
profile
protect me from what i want

0개의 댓글