성장, 그리고 노력

부족하더라도 어제보다 더 잘해지자. 노력은 절대 배신하지 않는다.

React

CSS in 리액트 - Inline Style

제이콥(JACOB) 2020. 2. 1. 02:31

글을 시작하기 전에 넋두리...

 며칠 전 나는 간단한(?) 카드를 만드는 미니 프로젝트를 만들었다. 메인 라이브러리로는 평소 자주 사용하던 React를 사용했고, UI 라이브러리는 이뻐서 사용해 보고 싶었지만 기회가 없어 못 사용해봤던 antd를 사용했다. 그리고 다른 언어와 기술들을 조합하여 프로젝트를 완성했다. 

 사실 antd를 사용했더라도 당연히 내가 구현하고 싶은 방향과 UI/UX가 있기 때문에 CSS를 수정했다. 물론 리액트를 사용하며 inline CSS, *. css 방식, styled components, CSS-in-JS, scss (이건 조금?) 사용해본 경험은 있었지만, 빠르게 구현하자는 생각에 inline CSS를 통해 장바구니 앱을 구현했다.

 

"그런데 이렇게 구현하면 어떤 일이 일어났지?"

 왜 나는 Inline CSS를 사용하면서 왜 그렇게 했는지에 대해 생각하지 않았을까? 분명 처음에 리액트를 배울 때 배웠던거 같긴 한데 말이다. 무심코 사용했지만, 이렇게 사용하는 건 내가 개발자로서 추구하는 방향이 절대 아니다. 순간 너무 한심했지만, 이런 경험을 반복하기 싫어 다시 한번 정리해 본다. 


Inline styles 문제가 있을까?

 이 글을 읽기 전에 스스로 먼저 위 질문에 대한 답을 해보자. 

과연 인라인 스타일을 사용해서 리액트 컴포넌트를 스타일링한다면 문제가 생길까? 생긴다면 뭐가 생길까? 사실 인라인 스타일링 만큼 사용하기 간편한 건 없다. 특히나 UI 라이브러리를 사용하면서 작은 규모의 앱을 만든다면 더더욱 말이다.

 

그럼에도 불구하고 내가 말하고 싶은건 인라인 스타일을 피해야 한다는 것이다. 이유는 이전글에서 다뤘던 렌더링과 관련이 있다.

아래 예제는 create-react-app으로 만든 키보드 미러링이다. 내가 키보드로 타이핑하는 게 아래에 나타난다.

더보기
import React, { useState } from "react";

const ChildComponent = ({ contents }) => {
    return (
        <div
            style={{
                color: "blue",
                fontWeight: "bold",
                marginTop: "0.5rem"
            }}
        >
            {contents}
        </div>
    );
};

const App = () => {
    const [inputData, setInputData] = useState("");
    return (
        <div style={{ margin: "1rem" }}>
            <h1>렌더링 되는걸 보세요</h1>
            <input onChange={e => setInputData(e.target.value)} />
            <ChildComponent contents={inputData} />
        </div>
    );
};

export default App;

 

이름은 거창하지만, 심플..

 위에 코드에서 일반 HTML을 작성한거 같지만, 사실 JSX에 따라 작성했다. 그리고 JSX는 React.createElement(...)로 통해 변환되고 모든 속성이 props 객체의 일부가 된다. 그러다 보니 style 부분의 비교는 항상 false가 나올 수밖에 없고({} === {} // false), 다시 렌더링될때마다 스타일 객체가 다시 계산되어 성능이 저하될 수 있다

// ...

var ChildComponent = function ChildComponent(_ref) {
  var contents = _ref.contents;
  return _react.default.createElement("div", {
    style: {
      color: "blue",
      fontWeight: "bold",
      marginTop: "0.5rem"
    }
  }, contents);
};

// ...

 물론 이거 외에도 Inline CSS를 추천하지 않는 이유는 더 있다.

 

  • CSS 속성의 중복, 재사용성이 떨어진다.
  • 의사 클래스, 의사 요소, 미디어 쿼리, 키 프레임 애니메이션 같은 CSS의 기능을 온전하게 활용할 수 없다.
  • 앱의 규모가 커질수록 유지/보수가 어렵고 인라인 스타일이 많으면 코드 가독성도 떨어진다.
  • 리액트 공식 문서에서도 일반적으로는 추천하지 않는 방법이다.


TLDR;

만약 인라인 스타일을 사용한다면 결과적으로 React.PureComponent나 React.memo()의 이점이 사라진다. 꼭 인라인을 사용해야 한다면(CSS-in-JS 등을 배우기 위한 시간이나 여건이 안된다면), 아래와 같이 코드를 작성하는 것을 추천한다.

// Bad!
const ReactComponent = props => {
  return (
      <div
          style={{
              color: "blue",
              fontWeight: "bold",
              marginTop: "0.5rem"
          }}
      >
          {props}
      </div>
  );
};

// Good!
const styles = { color: "blue", fontWeight: "bold", marginTop: "0.5rem" };

const ReactComponent = props => {
    return <div style={styles}>{props}</div>;
};

 

반응형