コーダーに知っておいてもらいたい React JSX の基礎 その1

フロントエンド

Photo by Markus Spiske

皆様どうも、こんにちは!
こまりのフロントエンドエンジニア、桑木です。

せっかくだから近頃流行りのSPAを作ってみようかな? 今ならAngularかReactかVue.jsっぽい? うーん、Angularは巨大すぎて習得コストが半端ない、らしい。Vue.jsはアプリ規模が大きくなると、売りのシンプルさが逆に仇になるらしい。というような悪評を聞いたので、シンプルそうなReact、君に決めた!

という安直な理由でReact沼にハマったので(Reactそのものはシンプルだけどミドルウェア多すぎ問題)、ジタバタあがいて得た知見を弊社のコーダーに伝えるついでに記事にして行こうかと思います。弊社のコーダーはjQueryで何となくDOM操作ができる程度にはJavaScript(ES4)ができるので、その辺りの人が対象です。

JSX 概要

JavaScript Syntax eXtension(拡張構文JavaScript)の略だそうです。特殊な構文を追加したJavaScriptってことですね。

JSXはJavaScriptとは違って標準の規格があるわけではなく、JavaScriptを拡張したものなら誰でもJSXを名乗ることができます。なので、React用のJSX以外にもJSXを名乗る規格はありますが、今、ただ単にJSXといえばReactのJSXを指していると思って問題ないと思います。

というわけで、JSXといえばほぼReactとは言え標準化されてるというわけでもないので、ブラウザでは直接実行できません。実行する為にはトランスパイラという種類のソフトで、JSXではない素のJavaScriptに変換する必要があります。ちなみに、トランスパイラにはJavaScriptのバージョン(ES5とかES2015とかって奴)を変換する機能もあるので、少し古いブラウザでも最新のJavaScriptが使えるという利点もあります。

では、具体的にJSXのコードについて記述していきます。

JSX 記述法及びその内部動作

JavaScript中の文字列や数値などの代わりにHTMLのような物を直接記述します。

function render() {
    return <div id="message">テキストとか何か色々</div>;
}

HTMLっぽい部分以外は、全くJavaScriptそのものです。JavaScriptのコードはそのまま全て動きます。上記のコードはトランスパイラで、

function render() {
    return React.createElement('div', {id: 'message'}, 'テキストとか何か色々');
}

という感じのJavaScriptコードに変換されます。

React.createElementという関数の戻り値は、React専用のDOMオブジェクトです。Reactは専用のオブジェクトで色々な処理をした後、最終的にブラウザのDOMに変換して出力します。

タグが入れ子になっていると、

<div id="message"><span>テキストとか何か</span>色々</div>
==
React.createElement('div', {id: 'message'},
    React.createElement('span', null, 'テキストとか何か'),
    '色々'
)

このように引数に更にReact.createElementが入ったりして、React.createElementなどの引数として構造を保ったままJavaScriptのコードに変換されます。

色々説明しましたが、JSXを記述する上で実際にどのように変換されるかは全く気にする必要はありません。JSX中に記述された開始タグからそれに対応する終了タグまでの間が、一つの関数呼び出しに置き換わるだけです。しかし、その関数の引数として全ての子要素や属性値が指定される、という事実はJavaScriptのステートメント(if文やfor文などの制御構文や、varなどの宣言文等)をJSXのHTML中に記述できないことを意味します。ただし、繰返しや条件に応じた選択ができないという意味ではありません。

{ } で囲ってJavaScriptの式を埋め込む

ステートメントは使用できませんが、 { } で囲うことでテキスト要素や属性値としてJavaScriptの式を記述することができます。

<div>1 + 1 = { 1 + 1 }</div> // 1 + 1 = 2

var foo = "Some text!";
<div>変数fooは「{ foo }」です!</div> // 変数fooは「Some text!」です!
<div>{ foo.substr(2) }</div> // me text!

var bar = "bar_container";
<div id={ bar }>属性値にも使えるよ!</div>

JavaScriptにおいて式とは1 + 1のようなもっともらしいものだけでなく、ステートメント(制御文や宣言文等)以外は全て式として扱われます。上記のコードのようにたとえ変数名単体であっても式ですし、関数呼出しや変数への代入も式です。JavaScriptには関数宣言に似た記述で関数式という物もありますが、これもまた式です。

どれが式でどれが式でないかを一々理解する必要はありませんが、JSXを記述する上でif文やfor文を使わずに式だけで条件判定や繰返しを実現する方法は知っておいて損はありませんし、他人が書いたコードを読む上でその理解の助けになるでしょう。

次回へ続きます。