# 주의 사항

## 속성 이름은 camelCase&#xB85C;*!*

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

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

{% hint style="info" %}

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

애플리케이션 접근성 향상을 위한 표준 기술 [WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1) 속성 및 상태(aria-\*)는 HTML 표준 속성과 동일한 하이픈 케이스(hypen-case) 표기법을 사용 합니다.

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

보다 자세한 내용은 [접근성(Accessibility)](https://ko.reactjs.org/docs/accessibility.html#wai-aria) React 공식 문서를 참고하세요.
{% endhint %}

## 콘텐츠가 없는 요소는 항상 닫아&#xC57C;*!* <a href="#always-close-empty-element" id="always-close-empty-element"></a>

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

```jsx
<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>
```

## 루트 요소는 하나만 사&#xC6A9;*!* <a href="#one-root-element" id="one-root-element"></a>

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

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

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

{% hint style="danger" %}

#### 오류 메시지

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

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

```jsx
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](https://ko.reactjs.org/docs/react-api.html#reactfragment) 요소를 사용해 버튼 요소들을 래핑(Wrapping) 할 수 있습니다.

```jsx
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>` 요소는 다음과 같이 `<></>` 별칭으로 대체해 사용할 수도 있습니다.

```jsx
import React from 'react'

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

{% hint style="info" %}
&#x20;\<div> 요소와 달리 \<React.Fragment> 요소는 실제 DOM에 그려지지 않습니다.
{% endhint %}

{% hint style="warning" %}

#### Vue의 래핑(템플릿)

vue에서는 [\<template>](https://v3.ko.vuejs.org/guide/list.html#template-%E1%84%8B%E1%85%A6%E1%84%89%E1%85%A5%E1%84%8B%E1%85%B4-v-for)을 사용해 React의 Fragment와 비슷한 일을 처리합니다.
{% endhint %}
