주의 사항

JSX를 사용할 때 주의할 점

속성 이름은 camelCase로!

JSX는 HTML이 아닙니다. XML 구문과 유사한 JavaScript 식이므로 React DOM은 HTML 표준 속성 이름 중 일부는 그대로 이름을 사용할 수 없습니다. 예를 들어, JSX에서 classclassName으로, tabindextabIndex로 사용해야 합니다. (네이밍 패턴: 음절이 2개 이상인 경우 camelCase로 표기)

<div className="container" tabIndex="-1">
  /* ... */
</div>

잠깐! 접근성 속성은 조금 달라요.

애플리케이션 접근성 향상을 위한 표준 기술 WAI-ARIA 속성 및 상태(aria-*)는 HTML 표준 속성과 동일한 하이픈 케이스(hypen-case) 표기법을 사용 합니다.

<div aria-label="키보드 컨트롤 도움말" role="group">
  /* ... */
</div>

보다 자세한 내용은 접근성(Accessibility) React 공식 문서를 참고하세요.

콘텐츠가 없는 요소는 항상 닫아야!

JSX는 XML 문법에 따라 콘텐츠가 없는 빈 요소(empty element)는 반드시 닫아(/>) 줘야 합니다. (예: <img/>, <br/>, <area/> 등)

<div className="empty-elements">
  <img src={image.src} alt={image.alt} />
  <br />
  <map>
    {mapItems.map(item => (
      <area 
        key={item.key}
        shape={item.shape} 
        coords={item.coords} 
        href={item.href} 
        title={item.title} 
      />
    ))}
  </map>
</div>

루트 요소는 하나만 사용!

JSX는 루트 요소를 하나만 가져야 합니다. 그러므로 다음과 같은 코드는 오류 처리됩니다.

// 구문 해석 오류 발생!
const ButtonGroup = (
  <button type="button" className="button button__save">저장</button>
  <button type="button" className="button button__cancel">취소</button>
)

React는 사용자에게 문제가 발생한 원인과 해결책을 오류 메시지를 통해 알려줍니다.

오류 메시지

Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?

오류가 알려준대로 버튼 요소들을 묶는 하나의 루트 요소(예: <div></div>)를 추가 하거나,

const ButtonGroup = (
  <div className="button-group">
    <button type="button" className="button button__save">저장</button>
    <button type="button" className="button button__cancel">취소</button>
  </div>
)

React Fragment 요소를 사용해 버튼 요소들을 래핑(Wrapping) 할 수 있습니다.

import React from 'react'

const ButtonGroup = (
  <React.Fragment>
    <button type="button" className="button button__save">저장</button>
    <button type="button" className="button button__cancel">취소</button>
  </React.Fragment>
)

그리고 <React.Fragment> 요소는 다음과 같이 <></> 별칭으로 대체해 사용할 수도 있습니다.

import React from 'react'

const ButtonGroup = (
  <>
    <button type="button" className="button button__save">저장</button>
    <button type="button" className="button button__cancel">취소</button>
  </>
)

<div> 요소와 달리 <React.Fragment> 요소는 실제 DOM에 그려지지 않습니다.

Vue의 래핑(템플릿)

vue에서는 <template>을 사용해 React의 Fragment와 비슷한 일을 처리합니다.

Last updated