0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【第十三回】TSXの正体について

0
Posted at

このセクションもいよいよ佳境です。今回はTSXの正体について学習していきます。

これまで何度か言及してきましたが、TSXはあくまでTypeScriptのオブジェクトとして扱うことができます。一見ただのHTMLに見えますが、オブジェクトなので変数に代入したり、propsとして他のコンポーネントに渡したりできるわけです。

コンソールで中身を見てみる

まずは実際に確認してみましょう。

//Greet.tsx
import "./Greet.css"
const Greet = ()=> {
  const sample = <h3>Hello TSX</h3>;

  console.log(sample);

  return (
    <div className="component">
      {sample}
    </div>
  );
}

export default Greet;

HTMLではなく、TypeScriptのオブジェクトが表示されました。

TSXは関数呼び出しに変換される

ではどうやってオブジェクトになるのでしょうか?

TSXは、ビルド時に関数呼び出しの形に変換されています。<h3>Hello TSX</h3>は、現行のReactではこう変換されます。

import { jsx as _jsx } from "react/jsx-runtime";

_jsx("h3", { children: "Hello TSX" });

この_jsx()が、オブジェクトを作るための関数ということになります。

なお古い解説では、変換結果がReact.createElement("h3", null, "Hello TSX")と書かれていることがあります。こちらはReact16以前の変換方式で、React17からreact/jsx-runtimeを使う方式が導入されました。

第三回で作成したNext.jsのプロジェクトは新しい方式の設定になっているので、import React from "react"を書かなくてもタグが動きます。

できあがるオブジェクトが「React要素」

この関数が実行されてできるオブジェクトをReact要素と呼びます。

{
  type: "h3",                        // タグの種類
  key: null,                         // リスト表示で使う目印
  props: { children: "Hello TSX" },  // 属性と、タグに挟んだ中身
}

第1引数のタグの種類がtypeに入り、属性がpropsに入ります。

そしてここが重要なのですが、タグに挟んだ中身はprops.childrenに入ります。前回childrenが特別に見えたのは、Reactが特別なルールを作ったからではなく、変換の時点でそこに詰め込まれているからです。

オブジェクトとして操作できる

オブジェクトである以上、オブジェクトにできる操作は何でも行えます。

//Greet.tsx
const Greet = ()=> {
  console.log((<div className="component">Hello</div>).props);

  return (
    <div className="component">
      <h3>Hello World</h3>
    </div>
  );
}

コンソールには{ className: "component", children: "Hello" }と表示されます。propsオブジェクトを取り出すこともできました。

入れ子にするとツリーになる

タグが入れ子になっている場合はどうなるでしょうか。第五回で作成したGreetはこういう構造でした。

//Greet.tsx
const sample = (
  <div className="component">
    <h3>Hello World</h3>
    <List />
  </div>
);

この場合、divのReact要素のchildrenの中に、h3ListのReact要素が入ります。

div のReact要素
├── h3 のReact要素
└── List のReact要素

コンソールでchildrenを開いていくと、実際にそうなっていることが確認できます。

このように入れ子になった場合、React要素はツリー状に構成されていきます。こういったものをReact要素のツリーと呼びます。

Reactはこのツリーをもとにして画面を構成するので、このコンセプトはぜひ覚えておいてください。

用語の整理

用語 意味
JSX HTMLに似た記法そのものの正式名称。ツールの設定名にもこの名前が使われる
TSX JSXをTypeScriptファイル(.tsx)で書いたもの。中身はJSXと同じ
React要素 変換後の関数が実行されてできるオブジェクト。type / props / keyを持つ
React要素のツリー React要素が入れ子でつながった構造
仮想DOM 上のツリーを指す通称

ここで1つ疑問

ここまで読み進めてきた中で、ある疑問を抱いた方がいるかもしれません。

それは、**コンポーネント自体はReact要素なのか?**ということです。

React要素の定義は「変換後の関数が実行されてできるオブジェクト」でした。それを前提に、少し考えてみてください。

確認問題

以下のTSXについて考えてみましょう。

<h3 className="title">Hello World</h3>

問題

  1. このTSXが変換されたあとの関数呼び出しを書いてください
  2. その関数が実行されてできるReact要素のtypepropsが、それぞれどうなるか答えてください
  3. Hello Worldという文字列は、React要素のどこに入るか答えてください

(下に解答を記載しています)

解答

1. 変換後の関数呼び出し

_jsx("h3", { className: "title", children: "Hello World" });

2. React要素の中身

{
  type: "h3",
  key: null,
  props: { className: "title", children: "Hello World" },
}

typeにはタグの種類である"h3"という文字列が入り、propsには属性が入ります。

3. 文字列が入る場所

props.childrenに入ります。

タグに挟んだ中身はchildrenというプロパティに詰め込まれる、というのが変換のルールです。前回学んだchildrenが特別に見えたのは、この仕組みによるものでした。

チェックリスト

  • TSXはビルド時に関数呼び出しに変換されると理解している
  • 変換後の関数が実行されてできるオブジェクトをReact要素と呼ぶ
  • React要素はtype / props / keyを持っている
  • タグの種類がtypeに、属性がpropsに入る
  • タグに挟んだ中身はprops.childrenに入る
  • console.logでReact要素の中身を確認した
  • React要素からは.propsのようにオブジェクトとして値を取り出せる
  • 入れ子にするとReact要素のツリーになると理解している
  • 仮想DOMがこのツリーを指す通称だと知っている

第十三回はここまで。
次回は実際にコードを動かしながら、この疑問について確認していきます!

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?