Step by Step

React Study(8) - 리액트를 다루는 기술 9장 본문

React

React Study(8) - 리액트를 다루는 기술 9장

짤진이 2023. 2. 6. 20:58
반응형

#9장 컴포넌트 스타일링
리액트에서 컴포넌트를 스타일링할 때는 다양한 방식을 사용할 수 있다. 여러 방식 중에서 딱히 정해진 건 없다.
• 일반 CSS : 컴포넌트를 스타일링하는 가장 기본적인 방식
• Sass : 자주 사용되는 CSS 전처리기 중 하나로 확장된 CSS 문법을 사용하여 CSS 코드를 더욱 쉽게 작성하게 한다
• CSS Module : 스타일을 작성할 때 CSS 클래스가 다른 CSS 클래스의 이름과 절대 충돌하지 않도록 파일마다 고유한 이름을 자동으로 생성
• styled-components : 스타일을 자바스크립트 파일에 내장시키는 방식으로 스타일을 작성함과 동시에 해당 스타일이 적용된 컴포넌트를 만듬

컴포넌트 스타일링 실습 과정
프로젝트 준비하기 -> 일반 CSS 사용하기 -> Sass 사용하기 -> CSS Module 사용하기 -> styled-components 사용하기

9.1 일반 CSS
CSS를 작성할 때 가장 중요한 점은 CSS 클래스를 중복되지 않게 만드는 것이다.

9.1.1 이름 짓는 규칙
프로젝트에 자동 생성된 App.css를 읽어보면 클래스 이름이 컴포넌트 이름-클래스 형식으로 지어져 있다.(예: App-header)
비슷한 방식으로 BEM네이밍이라는 방식도 있는데 CSS 방법론 중 하나로, 이름을 지을 때 일종의 규칙을 준수하여 해당 클래스가 어디에서 어떤 용도로
사용되는지 명확하게 작성하는 방식이다.

9.1.2 CSS Selector
CSS Selector를 사용하면 CSS 클래스가 특정 클래스 내부에 있는 경우에만 스타일을 적용할 수 있다.
예를 들어 .App 안에 있는 .logo에 스타일을 적용하고 싶다면 아래처럼 작성하면 된다.

.App .logo {
    animation : App-logo-spin infinite 20s linear
    height : 40vmin;
}



9.2 Saas 사용하기
Sass는 CSS 전처리기로 복잡한 작업을 쉽게 할 수 있도록 해주고 스타일 코드의 재활용성을 높여줄 뿐만 아니라 코드의 가독성을 높여서 유지 보수를 쉽게 해준다.

<.sass>
$font-stack: Helvetica, sans-serif
$primary-color: #333

body
    font:100% $font-stack
    color: $primary-color



<.scss>
$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body{
    font: 100% $font-stack;
    color: $primary-color;
}



9.3 CSS Module
CSS Module은 CSS를 불러와서 사용할 때 클래스 이름을 고유한 값 즉 파일이름_클래스_해시값 형태로 
자동으로 만들어서 컴포넌트 스타일 클래스 이름이 중첩되는 현상을 방지해주는 기술이다.

<CSSModule.module.css>

/* 자동으로 고유해질 것이므로 흔히 사용되는 단어를 클래스 이름으로 마음대로 사용 가능*/

.wrapper {
    background: black;
    padding: 1rem;
    color: white;
    font-size: 2rem;
}
.inverted {
    color: black;
    background: white;
    border: 1px solid black;
}

:global .something{
    font-weight: 800;
    color: aqua;
}


<CSSModule.js>

import styles from './CSSModule.module.css';

const CSSModule = () => {
    return (
        <div className={'${styles.wrapper} ${styles.inverted}'}>
            안녕하세요, 저는 <span className="something">CSS Module!</span>
        </div>
    );
};
export default CSSModule;


ES6 문법 템플릿 리터럴을 사용하여 문자열을 합했다.
템플릿 리터럴 문법을 사용하고 싶지 않다면 다음과 같이 작성 가능하다.
className = {[styles.wrapper, styles.inverted].join(' ')}

9.3.1 classnames
classnames는 CSS 클래스를 조건부로 설정할 때 매우 유용한 라이브러리입니다.
또한 CSS Module을 사용할 때 이 라이브러리를 사용하면 여러 클래스를 적용할 때 매우 편리하다.

9.3.2 Sass와 함께 사용하기

<CSSModule.module.scss>

/* 자동으로 고유해질 것이므로 흔히 사용되는 단어를 클래스 이름으로 마음대로 사용 가능*/

.wrapper {
    background: black;
    padding: 1rem;
    color: white;
    font-size: 2rem;
    &.inverted{
        //inverted가 wrapper와 함께 사용될때만 적용
        color: black;
        background: white;
        border: 1px solid black;
    }
}

:global {
    .something{
        font-weight: 800;
        color: aqua;
    }
}



9.4 styled components
컴포넌트 스타일링의 또 다른 패러다임은 자바스크립트 파일 안에 스타일을 선언하는 방식이다.

$ npm add styled-components
styled-components를 사용하면 자바스크립트 파일 하나에 스타일까지 작성할 수 있기 때문에 .css .scss확장자를 가진 
스타일 파일을 따로 만들지 않아도 된다는 큰 이점이 있다.

<StyledComponents.js>

import styled, {css}from 'styled-components';

const Box = styled.div`
    background: ${props => props.color || 'blue'};
    padding: 1rem;
    display: flex;
    `;

const Button = styled.button`
    background: white;
    color: black;
    border-radius:4px;
    padding: 0.5rem;
    display: flex;
    align-items: center;
    justify-content:center;
    box-sizing:border-box;
    font-size: 1rem;
    font-weight: 600;
    
    &:hover {
        background: rgba(255,255,255,0.9);
    }
    
    ${props => 
    props.invertes &&
    css`
        background: none;
        border: 2px solid withe;
        color: whtie;
        &:hover{
            background: white;
            color:black;
            }
        `};
    & + button{
        margin-left: 1rem;
    }
    `;

const StyledComponent = () => (
    <Box color="black">
        <Button>안녕하세요</Button>
        <Button inverted={true}>테두리만</Button>
    </Box>
);
export default StyledComponent;


<App.js>

import {Component} from 'react';
import StyledComponent from './StyledComponent';

class App extends Component {
  render() {
    return (
      <div>
        <StyledComponent/>
      </div>
    );
  }
}
export default App;

추가로 이런 상황에서는 takejson파일에서 react-scripts 버전을 확인하고 버전 5이상인지 한번 확인해보면 좋을 것 같다.

반응형