React 애플리케이션의 스타일을 지정하는 가장 좋은 방법

파이리·2023년 7월 27일

React

목록 보기
8/9
post-thumbnail

원문 : https://blog.devgenius.io/best-ways-to-style-a-react-js-application-c818b71f6341


React-JS 프로젝트를 시작할 때마다 일반적으로 이 특정 프로젝트에서 스타일링 방법론에 따라야 할지에 대해 논의합니다. 따라서 다음 스타일링 옵션에 대해 논의하고 각 옵션의 장단점과 제가 개인적으로 선호하는 스타일에 대해 설명하겠습니다.

  • Inline styles
  • Global style file
  • SASS/SCSS
  • CSS modules
  • CSS-in-JS

Introduction

우선, 스타일링 옵션을 고려할 떄 다음과 같은 측면을 고려해야 하며, 이를 중심으로 스타일링 옵션을 비교하겠습니다.

  • 유지 관리성
  • 재사용성
  • 의사 클래스 등과 같은 CSS 기능 여부
  • 스타일링 중 자바스크립트 로직의 적용 여부
  • 성능
  • 디버깅
  • 난이도
  • 프로젝트 크기

Inline Styles

인라인 스타일은 JSX 요소의 style 프로퍼티에 모든 스타일을 전달할 때 사용합니다. 이러한 스타일은 자바스크립트 객체로 전달되며 일반 자바스크립트에서 사용하는 모든 변수를 사용합니다.

const styles = {
    backgroundColor: 'red',
    color: 'blue'
}
return (<div style={styles}>some text</div>)

스타일 어떻게 카멜 케이스 형식으로 되어 있는지 주목하세요. 또한 스타일은 문자열로 전달됩니다.

장점

  • 소규모 프로젝트에서 구현하기 쉬움
  • 외부 스타일시트가 필요하지 않아 랜더링할 페이지가 하나 줄어듭니다.
  • 스타일에서 자바스크립트 로직을 쉽게 적용가능
  • 디버깅이 쉬움
  • 숫자를 값으로 입력하면 React가 자동으로 px 단위로 변환

단점

  • 재사용 및 유지 괸리가 어려움
  • 의사 클래스, 의사 요소, 미디어 쿼리 등 CSS 기능을 구현할 수 없음
  • 리액트 앱에서는 랜더링되는 파일이 많아 모두 인라인 스타일을 사용하면 성능에 부정적인 영향을 끼칠 수 있음

결론

제 애플리케이션에서는 시간이 매우 부족하거나 작은 컴포넌트 혹은 작은 프로젝트를 만드는 경우가 아니라면 인라인 스타일을 선호하지 않습니다.

인라인 스타일링은 자바스크립트 객체이고 리액트 상태와 호환되므로 상태를 사용하여 소규모 프로젝트의 스타일링을 조작할 수 있습니다.

Global CSS file

전역 스타일링은 React 프로젝트에 전체 스타일 파일을 빌드하는 App.css 혹은 index.css 파일이 있는 경우입니다. App.js에서 스타일 파일을 가져옵니다.

import React from 'react';
import './App.css';
import MyApp from './MyApp';
const App = (props) => {
   return <div className="app">
            <MyApp />
          </div>
}
export default App

모든 컴포넌트에서 모든 클래스를 사용할 수 있습니다.

import React from 'react';
const MyApp = (props) => {
   return(
    <div className="my-app">Hello</div>
   )
}
.my-app {
    background-color: red;
 }
.app {
    font-size: 16px;
 }

몇가지 중요한 사항이 있습니다.

  • 모든 컴포넌트에서 각 컴포넌트의 스타일 시트를 가져오는 것이 아닙니다.
  • 컴포넌트에서 className 프로퍼티를 사용하면 어느 컴포넌트에서나 액세스 할 수 있으며, CSS 스타일시트의 범위는 전역입니다.
  • 스타일은 자바스크립트의 인라인 CSS처럼 되어 있지 않고, 적절한 CSS 형식을 따릅니다.

장점

  • 유지 관리가 덜 필요하고 예산 리소스가 적게 드는 소규모 프로젝트를 빠르게 구축하는데 매우 좋음
  • CSS 모듈과 같이 많은 CSS 파일에 비해 랜더링할 CSS 파일이 하나뿐입니다.
  • 바닐라 자바스크립트 프로젝트에서 ReactJS 외부에서 편안하게 작업가능

단점

  • 유지 관리가 어려움
  • 새로운 기능를 추가하는 것이 매우 어려움
  • 특정 사용 사례만 충족
  • 명명 규칙을 익혀야 하며 그렇지 않으면 문제가 발생함 ( 이름 충돌 등 )
  • 자바스트립트 로직을 구현할 수 없어 동적 스타일이 어려움
  • 테마 지정이 어려움

결론

극히 짤은 시간에 재한된 기능과 매우 적은 수의 페이지로 구성된 소규모 프로젝트이고, 유지 관리에 돈을 쓰지 않을 경우 적절합니다.

SASS/SCSS

SASS는 CSS 전처리기입니다. 간단히 말해, 프로덕션 전에 모든 코드를 하나의 전역 CSS 파일로 컴파일합니다. SASS로 스타일링을 하는 동안 프로그래머같은 느낌을 줍니다. 이는 함수, 믹스인, 루프 등 스타일링에서 동적인 로직을 만들 수 있기 때문입니다.

장점

  • 학습 곡선이 완만하고 CSS 이후에도 매우 쉽게 배울 수 있습니다.
  • 배열, 객체, 프로젝트 폴더 구조, 로직 등을 배우기 떄문에 CSS를 배운 후 바로 자바스크립트를 배우는 것과 달리 프로그래밍과 알고리즘적 사고에 입문하는데에 도움이 됩니다.
  • 많은 레거시 프로젝트가 SASS로 진행되기 때문에 커뮤니티의 지원이 풍부하고 알려진 많은 문제가 수정된다는 점이 장점입니다.

단점

  • SASS는 스타일링 내부에 로직이 있지만 스타일에 Javasript를 포함할 수 있는 방법이 없습니다. 따라서 동적 스타일링을 적용하려면 조건부 클래스 이름에 의존해야 합니다.
  • SASS는 브라우저 개발 도구와 호환되지 않기 때문에 디버깅이 매우 불편합니다.
  • SASS는 다른 React 라이브러리와 호환되지 않습니다.
  • 클래스 이름이 충돌될 수 있습니다.

결론

  • 언급된 단점에도 불구하고 앞선 업근한 장점으로 인해 React로 SASS를 배우는 것은 큰 자산입니다. 수많은 사용자가 있는 레거시 프로젝트에서 경험을 쌓을 수 있고, 따라서 외부 라이브러리가 많지 않은 클래스 기반 컴포넌트에서 레거시 React 프로젝트에서 사용되는 코딩 패턴을 이해하는 데 도움이 됩니다.
  • React 컴포넌트와의 연결성을 부족하기 떄문에 프로젝트에서 SASS를 사용하고 싶지 않습니다. 저는 clssx를 사용하여 상태를 조건부로 스타일에 전달하여 동적으로 만들고 반응 상태와 호환되로록 하는 방법을 이해합니다. 그러나 이모션이나 스타일 컴포넌트 같은 CSS in JS 라이어브러에 대해 논의할 떄 동적으로 스타일을 지정하는 것이 얼마나 쉬운지 알게 됩니다.

CSS 모듈

모든 CSS 파일에는 전역 범위가 있습니다. 즉, 실수로 클래스 이름을 오버라이드하는 경우가 매우 흔합니다. 따라서 CSS 모듈을 사용하면 필요한 JSX 컴포넌트로만 범위가 제한된 로컬 CSS 파일을 갖게 됩니다.

예를 들어 Component.jsx 라는 파일이 있는 경우 해당 스타일 파일을 빌드하려면 .module.css로 이름을 바꿔야 합니다.

import styles from './Component.module.css'

이제 클래스 이름을 변수로 전달합니다.

.button {
    background: red;
}
import React from 'react'
import styles from './Component.module.css'
const Component = (props) => {
     return (<div className={styles.button}>Hello</div>
}
export default Component

이제 리액트가 이 클래스에 고유한 이름을 부여함으로 앱의 다른 곳에서 이 버튼 클래스를 사용해도 이름이 충돌하지 않습니다.

이는 로컬 클래스 이름 때문에 글로버 SCC와 SASS에서 크게 개선된 점이빈다. 따라서 재사용 가능한 UI 객체를 빌드하려면 해당 컴포넌트에 해당하는 module.css 파일만 빌드하면 됩니다. 따라서 재사용 가능한 React 컴포넌트에만 첨부되므로 컴포넌트 재사용의 복잡성이 줄어들고 이름 충돌이 발생하지 않아 유지보수가 쉬워집니다.

장점

  • 재사용 가능한 React 구조를 지원합니다. 해당 컴포넌트가 재사용 가능한 경우 스타일도 재사용할 수 있습니다.
  • 이름 충돌이 없어 유지보수에 좋음
  • 프로젝트 크기가 작아 SASS에 비해 성능이 유리합니다.
  • 새로운 개발자가 클래스 이름을 기반으로 스타일을 재정의하여 특정 컴포넌트를 쉽게 개선할 수 있습니다.

단점

  • 컴포넌트 상태에 대한 연결이 없음으로 내부에 논리적 패턴이 없습니다.
  • 새로운 개발자가 배우기 번거로울 수 있는 레거시 리액트 프로젝트를 위한 웹팩 전용 구성이 필요합니다.
  • 자바스크립트 로직 사용 불가
  • 객체 구조로 인해 단일 컴포넌트에서 여러 클래스를 첨부하기 어려움.
  • 커뮤니티의 지원이 적음
  • 테마와 호횐되지 않음
  • 확장성이 없음

결론

프로젝트를 받았는데 마감 기한이 매우 짧고 스타일을 재정의하여 작은 디자인 버그를 빠르게 수정하고 싶을 때 CSS 모듈을 사용할 것입니다. 그 외에는 훨씬 더 많은 이점을 제공하는 다른 스타일링 옵션이 있기 떄문에 CSS 모듈을 선택하지 않을 것입니다.

CSS-in-JS

CSS-in-JS는 자바스크립트 파일 내에서 CSS를 사용하여 클래스로 전달하는 스타일링 옵션입니다. 이 과정은 JavaScript를 사용하여 스타일을 요소에 전달하면 컴파일러가 이를 CSS로 변환하여 적절하게 첨부하는 방식입니다.

다음과 같이 CSS-in-JS 프레임워크를 기반으로 구축된 많은 라이브러리가 있습니다.

  • JSS
  • Emotion
  • Styled Component

CSS-in-JS를 이야기할 때, 이 기능을 수행하는 많은 라이브러리가 있다는 점에 유의하는 것이 중요합니다. 하지만 제가 개인적으로 좋아하는 것은 스타일드 컴포넌트입니다. CSS-in-JS는 모두 거의 동일한 기능을 제공하며 가장 많이 요구되는 스타일링 방식이라는 점에 유의해야 합니다. 유일한 차이점은 구문과 데이터가 전달되는 방식에 있습니다. 따라서 스타일드 컴포넌트는 문법이 가장 쉽기 때문에 가장 선호하는 방법입니다. 하지만 스타일드 컴포넌트에서 스타일을 prop로 전달하는 JSS나 이모션과 달리 컴포넌트의 이름을 지정합니다. 따라서 스타일 컴포넌트를 사용할 때 한 가지 작은 단점은 스타일 컴포넌트의 이름을 짓는데 어려움을 겪을 수 있습니다.

장점

  • 리액트 애플리케이션 스타일링의 가장 최신 사용 사례는 CSS-in-JS 접근 방식에 존재합니다.
  • 테마를 비롯한 다양한 상태와 props를 스타일링 솔루션에 직접 사용할 수 있습니다.
  • 변수를 사용할 떄 리액트 문법과 일치하는 화살표 함수 문법을 사용하여 변수를 전달할 수 있습니다. 또한 최신 함수형 패러다임에 따르기 때문에 매우 사용자 친화적입니다.
  • 서버 측 랜더링을 지원하며 타입스크립트도 지원합니다.
  • 모든 최신 라이브러리와 호환됩니다.
  • 확장성이 뛰어나고 유지 관리가 매우 쉽습니다.
  • 로컬 범위로 인해 이름 충돌이 없습니다.

단점

  • 브라우저 개발자 도구의 고유한 클래스 이름으로 인해 디버깅이 약간 어려움
  • 이전 ReactJS 버전과 호환되지 않음으로 레거시 프로젝트에서 흔히 사용되지 않습니다.
  • CSS-in-JS는 모든 스타일 정의를 바닐라 CSS로 파싱하여 index.html 파일의 스타일 태그 안에 모든 것을 넣습니다. 이렇게하면 HTML 파일 크기가 증가합니다.

결론

나는 일반적으로 CSS-in-JS를 사용합니다. 그 외에는 규모가 작고 즉시 사용 가능한 솔루션이 필요하며 CSS가 자바스크립트를 많이 포함되지 않은 경우입니다. 하지만 오래된 ReactJS 프로젝트, 클래스 기반 컴포넌트를 기반으록 구축된 프로젝트에서는 SASS를 사용합니다.

CSS-in-JS와 인라인 스타일은 차이점은 CSS-in-JS를 클래스 이름을 제공하고 인라인 스타일은 HTML 요소의 스타일 속성에 직접 스타일을 삽입합니다. 따라서 인라인 스타일은 성능 친화적이지 않습니다.

profile
프론트엔드 개발자

0개의 댓글