[React] React에서 Scss를 사용해보자 / TIL # 54

velg·2021년 10월 3일
0

React

목록 보기
7/10

React에서 Scss를 사용해보자

  • 해당 글에서 나오는 예제는 모두 Scss로 작성하였습니다

React에서 스타일 변경하기

html요소의 스타일을 변경하는방법은 여러가지가 있지만, 인라인이나 파일안에 직접 스타일요소를 적는 방법보단 css파일을 하나 생성하여 연결한 후 사용하는 방법을 사용하는게 일반적이다

React에서도 마찬가지이지만 방법이 살짝 다르다

스타일 파일과 연결하기

React는 js파일이기 때문에 html과 다르게 import로 해당 css파일을 연결한다
import 'css파일 path'

className

html에서 css파일의 셀렉터에 접근하는 방법은 다음과 같았다
class='클래스 이름'
하지만 React를 사용할 땐 js에 class라는 예약어가 이미 있기 때문에 className으로 접근해야한다 (마찬가지로 js임으로 class-name와 같은 이름은 쓰지 않는다)

실제 적용

그럼 위의 내용을 토대로 실제 프로젝트에 적용해보자

// App.js

import React from 'react';
import Button from './Button';
import './App.scss';

class App extends React.Component {
  render() {
    return (
      <main>
        <Button />
      </main>
    );
  }
}

export default App;

// button.js

import React from 'react';
import './Button.scss';

class Button extends React.Component {
  render() {
    return (
      <button className="button">
        버튼
      </button>
    );
  }
}

export default Button;

// App.scss
main {
  text-align: center;
}

// button.scss

.button {
  width: 100px;
  height: 30px;
  color: white;
  background-color: tomato;
}

App, Button 컴포넌트와 scss파일을 생성하고

<button className="button">버튼</button>

와 같이 className을 통해 스타일링을 해주었다

버튼

조건부 스타일링

위의 버튼을 스위치로 사용하고 싶고 그에 따라 on/off 상태에서 다른 배경색을 부여하고 싶으면 조건부 스타일링을 해야한다

하지만 위의 예처럼 고정된 값을 주면 조건부 스타일링을 할 수 없다
따라서 className에 변수를 할당해야한다

// onClick 이벤트를 통해 className의 배경색을 변경해보자
// button.js

import React from 'react';
import './Button.scss';

class Button extends React.Component {
  constructor() {
    super();
    this.state = {
      btnState: 'on',
    };
  }

  handleBtn = () => {
    this.state.btnState === 'on'
      ? this.setState({
          btnState: 'off',
        })
      : this.setState({
          btnState: 'on',
        });
  };

  render() {
    console.log(this.state.btnState);
    return (
      <button className={`Button ${this.state.btnState}`} onClick={this.handleBtn}>
        버튼
      </button>
    );
  }
}

export default Button;

// button.scss
.Button {
  width: 100px;
  height: 30px;
  color: white;

  &.on {
    background-color: tomato;
  }

  &.off {
    background-color: teal;
  }
}

위처럼 버튼을 눌렀을 시 배경색이 변경되는 것을 볼 수 있다
scss파일의 &는 부모를 의미한다
따라서 .Button.on .Button.off를 말하며 만약 &.을 적지 않았을 경우 제대로 적용이 되지 않는다

classnames 라이브러리

위와 같이 템플릿 리터럴을 이용해도 되지만 classnames라는 라이브러리를 사용하면 좀 더 편하게 조건부 스타일링을 할 수 있다

npm install classnames

<button className={classNames('Button', this.state.btnState)} onClick={this.handleBtn}>

classNames('Button', this.state.btnState)와 같이 사용 할 수 있다

꼭 써야할까요? 🤔
템플릿 리터럴의 경우 해당 속성이 셀렉터로 변환될 때 모든 문자열을 체크하기 때문에 띄어쓰기까지 일치하도록 해야한다

그렇기에 필자는 해당 라이브러리를 활용하는 편이 조금 더 좋아보이지만 항상 그렇듯 프로젝트, 팀원들의 사용여부에 따라 결정하는 것이 맞다고 생각한다

번외) SCSS 변수 활용하기
css에서도 변수를 사용 할 수 있지만 scss에서는에서는 좀 더 쉽게 변수를 선언해 사용 할 수 있다

$onColor: tomato;
$offColor: teal;

.Button {
  width: 100px;
  height: 30px;
  color: white;

  &.on {
    background-color: $onColor;
  }

  &.off {
    background-color: $offColor;
  }
}

$변수이름 : 값; 으로 변수를 선언하고 $변수이름으로 사용 할 수 있다

현재는 한 가지 경우에만 사용되는 컬러를 변수로 만들었기에 쓸모가 없어보이지만 해당 컬러가 프로젝트에서 자주 사용되는 컬러일경우 basicColor: #2d9a6d;와 같이 선언한 후 여러 곳에서 사용 하는 편이 좋다
(공통 css 폴더에 놓고 사용하기도 한다)

왜냐하면 여러곳에서 사용되는데 변수로 만들지 않고 사용한다면 #2d9a6d 값을 외워놓고 작성할 때마다 써야 할 것이기 때문이다

Mixin
만약 중복되는 코드가 있고, 조건에 따라 다른 스타일을 scss에서 구현하고 싶다면 Mixin 을 사용하면 된다

@mixin 이름(인자) {
    내용
}

.Button {
    @include mixin이름(전달할 값);
}
위와 같이 사용하면 중복코드를 제거하고 전달할 값에 따라 다른 스타일링이 가능하다
심지어 조건문도 작성이 가능하기 때문에 마치 프로그래밍 언어처럼 사용할 수 있다
@if 조건1 {
  내용
} @else if 조건2 {
  내용
} @else {
  내용
}
profile
초보 개발자

0개의 댓글