왜 class말고 className씀? (react)

HG·2024년 5월 28일
0

why

목록 보기
1/3

why react use 'className' 'htmlFor'일까?

문득 생각이 들었다.

사실 이전엔 class가 예약어이기 때문이라는 이유로 안된다고 하고 넘어갔었는데 다시 곱씹어보면 이상하다.

공식문서에서도 예약어로 다루고 있다. https://ko.react.dev/learn/writing-markup-with-jsx

근데 곰곰히 생각해보면, jsx로 된 컴포넌트를 렌더링(실행) 하면, React.createElement함수를 실행하는 것이다. 그리고 React.createElement가 어떻게 되었든, 결국 dom api를 내부적으로 동작시킬 것이다. 결국, dom apiattribute를 활용하여 element를 만들게 될 것이다.

'이러한 부분을 고려하여 만들어진게 아닐까?' 라고 생각하고 접근하기 시작했다.

reactjshtml을 만들어내는 과정을 추상화 하고 있다면, jsxhtml에 들어가는 tag들에 attribute를 넣는 과정은 dom api를 통해 attribute를 추가하는 과정과 일맥상통한다.

그래서 dom api를 살펴보면, setAttribute과정에 class는 없다. className은 존재하지만, class는 없다.

label 을 만들어보면 이 과정에서도 htmlFor 있지만, for은 없다.

그러니까 기본적으로 dom api를 만들때부터, dom api를 통해 생성하는 과정에서 key로 받을 값들에 classNamehtmlFor가 존재한 것이다.

근데 여기서 의문이 있다.

react 이정도도 모를까? 당연히 알고 있지 않을까? 그리고 이걸 해결하는 과정이 크게 안 복잡할 것 같다고 생각했다.

그리고 실제로 찾아보니 그들은 당연히 이 문제를 알고 있었다. 그리 어렵지 않다는 사실도 알고 있었고, 멘탈 모델상 classclassName대신 써야 한다는 입장도 많았던 것 같다.

class를 써야한다에 대한 의견

나도 동의한다. jsx를 사용하는 결과가 js객체로의 변환이어도, 사용성에 있어서는 html태그와 js코드를 혼합해서 작성한다.

멘탈모델에 있어서 html 태그에 기입하는 그대로 작성할 수 있도록 해놓는 것이 사용성에 있어서 더 맞지 않을까??라는 고민은 당연히 했듯이

리액트를 시작할때 마크업에 class를 사용해서 만들어도 문제가 되지 않은 겨험들이 있을 것 이다. 이 부분은 lint에서는 에러가 발생하지만, class 사용해도 문제없이 동작한다.

react 16버전부터는 class로 작성해도 가능하도록 해놓았다.

물론 lint가 빨간줄을 그어버리기 때문에 불편하지만, 그 마저도 수정하면 변경할 수 있긴하다.

  • 16이전의 react-dom.development.js

    
    var HTMLDOMPropertyConfig = {
    		...중략 ...
    autoPlay: HAS_BOOLEAN_VALUE,
    capture: HAS_BOOLEAN_VALUE,
    cellPadding: 0,
    cellSpacing: 0,
    charSet: 0,
    challenge: 0,
    checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
    cite: 0,
    classID: 0,
    className: 0,
    ... 중략 ...
    }}
  • 16이후 react-dom.development.js

    
    var possibleStandardNames = {
    // HTML
    ...중략 ...
    capture: 'capture',
    cellpadding: 'cellPadding',
    cellspacing: 'cellSpacing',
    challenge: 'challenge',
    charset: 'charSet',
    checked: 'checked',
    children: 'children',
    cite: 'cite',
    // 여기 있다.
    class: 'className',
    classid: 'classID',
    classname: 'className',
    ...중략...
    strokedasharray: 'strokeDasharray',
    'stroke-dasharray': 'strokeDasharray',
    strokedashoffset: 'strokeDashoffset',
    'stroke-dashoffset': 'strokeDashoffset',
    strokelinecap: 'strokeLinecap',
    'stroke-linecap': 'strokeLinecap',
    strokelinejoin: 'strokeLinejoin',
    'stroke-linejoin': 'strokeLinejoin',
    strokemiterlimit: 'strokeMiterlimit',
    'stroke-miterlimit': 'strokeMiterlimit',
    strokewidth: 'strokeWidth',
    'stroke-width': 'strokeWidth',
    strokeopacity: 'strokeOpacity',
    
    }
    
    if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
      var standardName = possibleStandardNames[lowerCasedName];
    
      if (standardName !== name) {
        error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
    
        warnedProperties$1[name] = true;
        return true;
      }
    }

    Invalid DOM property %s. Did you mean %s?' 이 부분은 익숙하다 Invalid DOM property class. Did you mean className 이걸로 만났었던 에러가 여기 있다. warning은 발생하지만 동작하는 것은 알 수 있다. warn에 넣어둔걸 보면 권장하지는 않는것 같다.

잘 살펴보면, stroke-linecap같이 늘 복붙해오면 딸려오는 마크업이 lint에서 에러를 뱉어내지만, 리액트 코드 내부적으로 해당 코드가 동작할 수 있게 작성해놓은 걸 알 수 있다.

참고
https://usage.tistory.com/143

profile
Making Body, Making Food, Making Co?de

0개의 댓글