10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

先生、どうしてReactでは class ではなくて className を使うの?

Last updated at Posted at 2024-11-07

問い

どうしてReactではclassでなくclassNameを使うのか?

結論

classJavaScript の予約語になっているため、やむを得ず className に改名している。

JSXとは

まず前提知識として、JSXについて少し知っている必要があります。

JSXとはjsの中にxmlライクな記述ができるようになった拡張構文で、

ブラウザで実行される前に、jsオブジェクトを生成する式に変換します。

例えば、以下のようなJSXがあるとします。

const button = <button type="submit" onClick={() => alert('クリックされました')}>送信</button>;

これは、ブラウザで実行される前に以下のjsに変換されます。

const button = React.createElement(
  "button",
  { type: "submit", onClick: () => alert('クリックされました') },
  "送信"
);

つまり、reactにおけるJSXとは、React.createElementを生成する記法ということになります。

React.createElementは公式にも説明がある通り、Reactの要素を生成するReactAPIなので、JSXから返却されるオブジェクトによってReact要素が生成されます。

JSXファイルの中でHTMLっぽく書けるのに、実はHTMLのプロパティとは全くの別物だった...!!

話は戻り、どうしてReactではclassでなくclassNameを使うのか?

JSXjsに変換されるので、JSX内でclassを使用するとjsのプロパティとして解釈されます。

しかし、jsには class の予約語が存在しているのでJSXでclassが使用されるのを避けています。

ちなみに同じ理由で改名を余儀なくされているのが for で、htmlForに改名されています。

以下余談

組み込みコンポーネント

Reactのコンポーネントには、以下の2種類が存在します

  • ユーザー定義コンポーネント
  • 組み込みコンポーネント

公式が公開しているのような組み込みコンポーネント以外に、
DOMコンポーネントもサポートしています。

以下のように一見、標準HTMLタグに見えるdivp組み込みコンポーネントに当たります。

const content = <div className="wrapper">Some content</div>

divにカーソルを当ててみると、それなりのpropを受け取ることができます。

このpropsの型の在処はinterface IntrinsicElementsに定義されています。

※ ちなみに、Intrinsic「〔人・物に〕本来備わっている、固有の、本質的な」という意味があります。

divなら以下のように定義されており、

div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;

React.HTMLAttributesは以下のように定義されている。

    interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
        // React-specific Attributes
        defaultChecked?: boolean | undefined;
        defaultValue?: string | number | readonly string[] | undefined;
        suppressContentEditableWarning?: boolean | undefined;
        suppressHydrationWarning?: boolean | undefined;

        // Standard HTML Attributes
        accessKey?: string | undefined;
        autoFocus?: boolean | undefined;
        className?: string | undefined;
        contentEditable?: Booleanish | "inherit" | "plaintext-only" | undefined;

        // ...略

これらがJSX divタグ が受け取れるpropsに繋がってくるというわけです。

複数の JSX タグを返す時にフラグメントでラップする

周知ですが、以下のようなコンポーネントではエラーが発生しますね。

export function Item() {
  return (
    <input type="text" placeholder="名前を入力" />
    <button type="submit" onClick={() => alert('クリックされました')}>送信</button>
  );
}

JSXは単一のタグを返却するというルールがあるので以下のような修正を加えるはずです。

export function Item() {
  return (
    <>
      <input type="text" placeholder="名前を入力" />
      <button type="submit" onClick={() => alert('クリックされました')}>送信</button>
    </>

  );
}

エラーになるからとりあえず従ったけど、どうしてなのか?

前述した通り、JSXHTML のように見えますが、「最終的にはJavaScriptオブジェクトに変換される」ということが分かっているならこれも理解できます。

公式のコラムに説明がありました。

関数から 2 つのオブジェクトを返したい場合、配列でラップしないといけませんよね。2 つの JSX タグを返したい場合に別のタグかフラグメントでラップしないといけないのも、同じ理由です

まとめ

公式より

JSX と React は別の物です。一緒に使われることが多いですが、片方だけを独立して使うことは可能です。JSX とは言語の拡張であり、React は JavaScript ライブラリです。

普段書いているReactがいかに純粋なJavaScriptであるかがわかりますね。

最後に

ここまで見ていただきありがとうございます!🙇
JSXについて知らなくても直感的に書けますが、知っているとよりReactと仲良くなれたような気がします。

参考

組み込みコンポーネント
DOMコンポーネント
interface IntrinsicElements
HTML を JSX に変換する

10
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?