JSXとお友達になろう

JSX書いてますか?ReactとともにJSXを書くことがあるかと思いますが、ReactなどのライブラリなしでJSXを使ってなにかすることは少ないのではないかと思います。

今回は、JSXを依存ライブラリなしで動かして、HTMLを出力させてみようと思います。以下の流れで説明していきます。

  1. Reactを使ってHTMLを出力する
  2. Reactを使ったときのトランスパイル後のコードを見る
  3. Reactを捨てて、自分でReactの穴を埋める
  4. JSXと仲良くなれる

Reactを使ってHTMLを出力する

まずは、Reactを使ってHTMLを出力できるようにしてみましょう。早速で恐縮ですが、今回はJSXではなくTSXで説明をしていきます。TypeScriptはTSXに対応しており、細かいことを考えなくてよくて楽なので。JSXでやりたい場合は、Babelなどを使っていただければと思います。

さて、まずは以下のコードをご覧ください。React + ReactDOMServerでHTMLを文字列としてconsole.logに吐くというプログラムです。簡単ですね。ブラウザの開発者ツールからconsole.logにどんなHTMLが出力されているか見てみるとよいでしょう。

Reactを使ったときのトランスパイル後のコードを見る

ここからの説明でもさきほどのサンプルプロジェクトをまだ使います。

CodePenの下に View Compiled というボタンがありますので、そちらを押してどのようなJSが吐かれているか見ることができます。見ていただくとわかるのですが、以下のような変換が行われています。

<div>
  <span>foo</span>
</div>

// ↓

React.createElement("div", null, 
  React.createElement("span", null, 
    "foo"
  )
)

コード中にHTMLタグのようなもの(JSX)を見つけたら、それを React.createElement という関数に食わせた形でJSに変換する。これこそがJSXの本質と言えます。

FacebookによるJSXのプロポーザルがありますので、読むとより理解が深まるでしょう。

Reactを捨てて、自分でReactの穴を埋める

勘のいい方はもうお気づきかと思いますが、本物のReactではなく、自分で定義したReactを置けば、Reactの代わりのフレームワークを作ることができそうですね。やってみましょう。

以下のように、Reactを入れていないのに(設定を見ないとわからないですが)、TSXを書いてもエラーが出ていませんね。例えば、Reactという変数定義を消せば、エラーになりますので、試してみてください。

上記のコードで、Reactの穴を埋める準備ができました。 では、HTMLを吐き出すコードを書いていきましょう。

書きました。

要は、 React.createElement という関数がオブジェクト(VNode)を生成し、 renderToString はVNodeを受け取って文字列に変換するようになっているわけです。これだけで ライブラリに依存せずにJSXを使ったアプリケーションを書けるようになりました(TypeScriptは必要ですが・・・)。

JSXと仲良くなれた

これまでのところでJSXとある程度仲良くなれたかと思います。思い思いのコードを書いていただいて自分だけのオリジナルのフレームワークを作ったり、あるいはフロントエンドという文脈から離れた何かを作るというのも手かもしれません。HTMLやJSONのような親子構造を構築するための構文として使えると思います。

したがって、ここから先は自分の目で確かめてみてくれということで、以上にします。

また、今回はCodePenを使用するため、React.createElementをオレオレ関数にしましたが、通常はそのような処理は不要で、例えばTypeScriptならtsconfig.jsonの設定で好きな名前の関数を設定することができますので、Reactというライブラリでなくても大丈夫です。

今回は説明しませんでしたが、俺の作った最強のReactを作るためにはさらに何段階かの壁を越える必要があります。 コンポーネント化や、状態管理、DOMの構築と再利用などです。ぜひやってみていただければと思います。よろしくお願いします。