Reactの続きです。前回はReactの仮想DOMをCDNで体験しました。今回はJSXのコンパイルを同じくCDNで体験します。ReactといえばJSX!なイメージだったのでようやく一歩踏み入れた感。それでは行きましょう!
【目次】
- 前回のおさらい
- 仮想DOMを入れ子構造のタグにする
- JSXとは何ぞや?
- CDNでJSXのライブラリを読み込む
- JSXコードを書く
- コンパイル後のJSコード
- JSXに値を埋め込む
- JSXのタグの中に属性を埋めこむ
- JSXのタグにstyle属性でCSSスタイルを当てる
- 最後に
前回記事
※参考:React事始め「すごいぞ!ReactはCDNで動いたんだ!」 - クモのようにコツコツと
Reactを習得するためにやったことまとめ qiita.com
前回のおさらい
前回作ったものはこちら。CDNリンクのためCodePenで作れている。
See the Pen React 02 by イイダリョウ (@i_ryo) on CodePen.
HTMLコード
<script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
react.development.js
とreact-dom.development.js
をCDNで読み込むと
<section> <h1>りあくと事始め</h1> <div class="text">読み込み中…</div> </section>
HTML上の.text
の文字は「読み込み中…」でも…
JSコード
//DOM取得 const text = document.querySelector('.text'); //DOMの中身設定 const elm = React.createElement( 'p', {}, 'こんにちは、りあくと。' ); //レンダリング ReactDOM.render(elm, text);
仮想DOMelm
の文字が読み込まれて「こんにちは、りあくと。」が画面に表示される。
※参考:React事始め「すごいぞ!ReactはCDNで動いたんだ!」 - クモのようにコツコツと
仮想DOMを入れ子構造のタグにする
今回も掌田さんの「React.js & Next.js超入門 」を参考に進めています。
- 作者:津耶乃, 掌田
- 発売日: 2019/03/08
- メディア: 単行本
上記の例では仮想DOMがp
タグ一つだが、これを入れ子構造の親子階層タグにするとどうなるか。
See the Pen React 04 by イイダリョウ (@i_ryo) on CodePen.
JSコード
//DOM取得 const text = document.querySelector('.text'); //DOMの中身設定 const elm = React.createElement( 'section', {class: "h2_elem"}, [ React.createElement( 'h2', {}, 'h2見出しです' ), React.createElement( 'p', {}, '入れ子で作られた仮想DOMですこれは。' ), React.createElement( 'ol', {}, [ React.createElement( 'li', {}, 'リストの1番目' ), React.createElement( 'li', {}, 'リストの2番目' ), React.createElement( 'li', {}, 'リストの3番目' ), React.createElement( 'li', {}, 'リストの4番目' ), ]), ]); //レンダリング ReactDOM.render(elm, text);
- 変数
elm
のReact.createElement()
の第3引数を配列に - 配列の中に入れ子で
React.createElement()
を書く - 仮想DOMの階層上、並列な要素は同様に第3引数を配列にする
- 属性(例:
section
のclass名.h2_elem
)は第2引数の連想配列で指定する
なお、子要素は配列で並列表現できるが一番外側の親要素は一つでなければならない。どうしても複数要素になる場合は全体をdiv
で囲う。
元のHTMLコードは変えていないが…
<section> <h1>りあくと事始め</h1> <div class="text">読み込み中…</div> </section>
画面上のHTMLコードはこうなっている。
<section> <h1>りあくと事始め</h1> <div class="text"> <section class="h2_elem"> <h2>h2見出しです</h2> <p>入れ子で作られた仮想DOMですこれは。</p> <ol> <li>リストの1番目</li> <li>リストの2番目</li> <li>リストの3番目</li> <li>リストの4番目</li> </ol> </section> </div> </section>
この方法で入れ子構造の親子階層を作ることができるが、JSコードのネストが深くてあまり直感的ではなくなってしまう…
JSXとは何ぞや?
ということで「そうだ、JSX使おう!」となったわけです!はい。ところでJSXとは何ぞや?
JSXは、JavaScriptの構文に対する拡張である[11]。HTMLと外観が似ているが、JSXは多くの開発者がよく知っている構文を使用して、構造化されたコンポーネントを描画する方法を提供する。Reactコンポーネントは、必須ではないが、通常はJSXを使用して書かれている
このJSXがHTMLの書式とソックリさん(細かい部分に違いはあるが)で、先ほどのネストの深い仮想DOMの階層をもっと直感的に表現することができる。
JSXってなんの略か
Reactで出てくるJavaScript syntax extension(以下、JSX)という単語
※参考:Reactで出てくるJSXという単語の意味 | エンジニアっぽいことを書くブログ
ふむ。シンタックスは「構文」でextensionは「拡張」という意味なので「JSの拡張構文」といった意味合いか。
CDNでJSXのライブラリを読み込む
そんでもってJSXのライブラリがまたまたCDNで読み込めるようだ!これによってローカル開発環境なしにCodePenで体験ができる。
以下のコードをhead
タグに追加(CodePenの場合は「JavaScript Preprocessor」を「Babel」にすればOK!)
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
なんと!JSXのライブラリって一つ前の記事で触れた「Babel」じゃないスか!!
※参考:【JS】BabelでESをコンパイルする - クモのようにコツコツと
BabelはES6以降の書式をES5にコンパイルするという理解だったがJSXのコンパイルも対応しているようだ!
もう一つ注意点としてはJSコードを書く部分のscript
タグにbabel
の属性を追記する。
<script type="text/babel"> //JSXで書かれたコード </scirpt>
こうしないとJSXで書かれた部分が認識されない。エラー(“Uncaught SyntaxError: Unexpected token <”
)になってしまった。
※参考:javascript - ReactJS: "Uncaught SyntaxError: Unexpected token <" - Stack Overflow
(先ほど書いたようにCodePenは「JavaScript Preprocessor」を「Babel」にすればOK!)
JSXコードを書く
JSコードをJSX書式に書き換える
//DOM取得 const text = document.querySelector('.text'); //JSXの中身 const elm = ( <section class="h2_elem"> <h2>h2見出しです</h2> <p>入れ子で作られた仮想DOMですこれは。</p> <ol> <li>リストの1番目</li> <li>リストの2番目</li> <li>リストの3番目</li> <li>リストの4番目</li> </ol> </section> ); //レンダリング ReactDOM.render(elm, text);
変数elm
を先ほどブラウザ画面でレンダリングされていたHTMLと同じ内容に差し替える。見た目がとてもシンプル!
全体を囲っているカッコ()
は無くても認識されるがJSXの境界をわかりやすくするために書いている。また、JSXでも一番外側のタグは一つだけなので一つにできない場合は全体をdiv
で囲う。
コンパイル後のJSコード
ちなみにCodePen上でコンパイル後のJSコード(「Vew Compiled JS」)を見るとこうなる。
//DOM取得 const text = document.querySelector('.text'); //h2テキスト const h2Text = "JSXはじめました"; //pタグテクスト const pText = "JSXに埋め込まれた値ですこれは。"; //JSXの中身 const elm = React.createElement("section", { class: "h2_elem" }, React.createElement("h2", null, h2Text), React.createElement("p", null, pText), React.createElement("ol", null, React.createElement("li", null, "\u30EA\u30B9\u30C8\u306E1\u756A\u76EE"), React.createElement("li", null, "\u30EA\u30B9\u30C8\u306E\uFF12\u756A\u76EE"), React.createElement("li", null, "\u30EA\u30B9\u30C8\u306E3\u756A\u76EE"), React.createElement("li", null, "\u30EA\u30B9\u30C8\u306E4\u756A\u76EE"))); //レンダリング ReactDOM.render(elm, text);
やはりReact.createElement()
のネストが入り組んでいて直感的ではない。
JSXに値を埋め込む
このままだとJSの中にただHTMLを埋め込んでいるだけなのでもう少しJSらしい動きを体験したい。JSXの中に外側の変数の値を埋め込んで見る。
See the Pen React 06 by イイダリョウ (@i_ryo) on CodePen.
見た目はほとんど同じだがJSXの部分を変えている。
//DOM取得 const text = document.querySelector('.text'); //h2テキスト const h2Text = "JSXはじめました"; //pタグテクスト const pText = "JSXに埋め込まれた値ですこれは。"; //JSXの中身 const elm = ( <section class="h2_elem"> <h2>{ h2Text }</h2> <p>{ pText }</p> <ol> <li>リストの1番目</li> <li>リストの2番目</li> <li>リストの3番目</li> <li>リストの4番目</li> </ol> </section> ); //レンダリング ReactDOM.render(elm, text);
- 変数
h2Text
にh2
タグに入れたいテキストを代入 - 変数
pText
にp
タグに入れたいテキストを代入 - JSXの
h2
タグの中にh2Text
を配置 - JSXの
p
タグの中にpText
を配置
JSX内に変数を配置する時は全体を波括弧{ }
で囲う。Vue.jsは二重波括弧{{ }}
だったがReactは一重のようだ。
JSXのタグの中に属性を埋めこむ
今度はタグの中に属性を埋め込んでみる。a
タグを作ってsrc
属性に値を埋め込む。
See the Pen React 07 by イイダリョウ (@i_ryo) on CodePen.
JSコード
//DOM取得 const text = document.querySelector('.text'); //JSXに埋め込む値 const h2Text = "JSX始めました"; const pText = "JSXに埋め込まれた値ですこれは。"; const ggrks = "わからないことはググろう"; const url = "https://www.google.com/"; //JSXの中身 const elm = ( <section class="h2_elem"> <h2>{ h2Text }</h2> <p>{ pText }</p> <p><a href={ url } target="_blank">{ ggrks }</a></p> </section> ); //レンダリング ReactDOM.render(elm, text);
- 変数
ggrks
にテキスト「わからないことはググろう」を代入 - 変数
url
にテキスト「https://www.google.com/」を代入 - リストを
p
タグに変更してa
タグを入れる a
タグのhref
属性にurl
を埋め込み、テキストにggrks
を埋め込む。
属性に埋め込む際は" "
で囲う必要がないのがポイント。
JSXのタグにstyle
属性でCSSスタイルを当てる
CSSを設定する方法はいくつかある。
- 外部のcssファイルを
link
属性でリンクする style
タグで囲った中にスタイルを書く- 一つ一つのタグの中に
style
属性でスタイルを書く
通常は外部のcssファイルに書くことが多いが、Reactはタグの中にstyle
属性で書くことが多いらしい。(昔のテーブルレイアウト時代を思い出す書き方だがスタイルの値は直書きではなく外部変数で共通化するため、メンテナンス上の不便はない)
やってみたのがこちら。
See the Pen React 08 by イイダリョウ (@i_ryo) on CodePen.
a
タグ「わからないことはググろう」にスタイルを当ててボタンにした。
//DOM取得 const text = document.querySelector('.text'); //JSXに埋め込む値 const h2Text = "JSX始めました"; const pText = "JSXに埋め込まれた値ですこれは。"; const ggrks = "わからないことはググろう"; const url = "https://www.google.com/"; //CSS設定 const ggrks_s = { display: "block", padding: "10px", borderRadius: "5px", textAlign: "center", color: "#fff", background: "#A63744", textDecoration: "none", } //JSXの中身 const elm = ( <section class="h2_elem"> <h2>{ h2Text }</h2> <p>{ pText }</p> <p><a href={ url } target="_blank" style={ ggrks_s }>{ ggrks }</a></p> </section> ); //レンダリング ReactDOM.render(elm, text);
- 変数
ggrks_s
に連想配列でスタイルを設定 - JSXの
a
タグのstyle
属性にggrks_s
を埋め込む
スタイルはパッと見CSSにソックリだがよく見ると違いがある。
- 連想配列なので値の区切りはセミコロン
;
では無くカンマ,
- 値はダブルコーテーション
" "
で囲う - プロパティ名が複数単語の場合ケバブケース(ハイフン
-
)では無くキャメルケース(大文字)で繋ぐ
キャメルケース、ケバブケース、スネークケース(アンダースコア_
)の違いについてはこちら
※参考:【極小ネタ】キャメルケース/スネークケース/チェーンケースの覚え方【変数の命名規則】 - Qiita
最後に
ということでJSXの基本的な部分を事始めました。BabelのCDNリンクでコンパイルできることは今回初めて知りました!
JSXは実際に始める前はJSコードの中にHTMLコードが組み込まれていることに違和感を感じていたのですが、こうしてReact.createElement()
の書式と比較してみるとやはりJSXの方がシンプルでわかりやすいと感じました。それに基本はDOMの階層構造のテンプレートなんだな、とイメージできました。
次回はJSXに関数を組み込んでみようと思います。それではまた!
Reactを習得するためにやったことまとめ qiita.com