JSX は、JavaScriptの構文拡張で、JavaScriptファイル内にHTMLのようなマークアップを記述することができます。コンポーネントを記述する方法は他にもありますが、ほとんどのReact開発者はJSXの簡潔さを好み、ほとんどのコードベースでJSXが使用されています。
学習内容
- Reactがマークアップとレンダリングロジックを混在させる理由
- JSXとHTMLの違い
- JSXで情報を表示する方法
JSX:マークアップをJavaScriptに埋め込む
WebはHTML、CSS、JavaScriptで構築されてきました。長年、Web開発者はコンテンツをHTMLに、デザインをCSSに、ロジックをJavaScriptに(多くの場合、別々のファイルに)分けてきました。コンテンツはHTML内でマークアップされ、ページのロジックはJavaScript内で別々に存在していました。


HTML


JavaScript
しかし、Webがよりインタラクティブになるにつれて、ロジックがコンテンツを決定することが多くなりました。JavaScriptがHTMLを制御するようになったのです。そのため、Reactでは、レンダリングロジックとマークアップがコンポーネントという同じ場所に一緒に存在します。


Sidebar.js
Reactコンポーネント


Form.js
Reactコンポーネント
ボタンのレンダリングロジックとマークアップを一緒にすることで、編集のたびに互いに同期した状態を保つことができます。逆に、ボタンのマークアップとサイドバーのマークアップのように、無関係な詳細は互いに分離されているため、どちらかを単独で変更しても安全です。
各Reactコンポーネントは、Reactがブラウザにレンダリングするマークアップを含むことができるJavaScript関数です。Reactコンポーネントは、JSXと呼ばれる構文拡張を使用して、そのマークアップを表します。JSXはHTMLによく似ていますが、少し厳格で、動的な情報を表示することができます。これを理解する最良の方法は、HTMLマークアップをJSXマークアップに変換することです。
HTMLからJSXへの変換
有効なHTMLがあるとします。
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
<li>Invent new traffic lights
<li>Rehearse a movie scene
<li>Improve the spectrum technology
</ul>
これをコンポーネントに配置したいとします。
export default function TodoList() {
return (
// ???
)
}
そのままコピーして貼り付けても、機能しません。
export default function TodoList() { return ( // This doesn't quite work! <h1>Hedy Lamarr's Todos</h1> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" class="photo" > <ul> <li>Invent new traffic lights <li>Rehearse a movie scene <li>Improve the spectrum technology </ul>
これは、JSXの方が厳格で、HTMLよりもルールがいくつか多いからです。上記のエラーメッセージを読めば、マークアップを修正する方法がわかります。または、以下のガイドに従ってください。
JSXのルール
1. 単一のルート要素を返す
コンポーネントから複数の要素を返すには、単一の親タグで囲みます。
たとえば、<div>
を使用できます。
<div>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</div>
マークアップに余分な <div>
を追加したくない場合は、代わりに <>
と </>
を記述できます。
<>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</>
この空のタグは、フラグメント と呼ばれます。フラグメントを使用すると、ブラウザのHTMLツリーに何も痕跡を残さずに要素をグループ化できます。
詳細解説
なぜ複数のJSXタグをラップする必要があるのですか? (リンクアイコン)
なぜ複数のJSXタグをラップする必要があるのですか? (リンクアイコン)
JSXはHTMLのように見えますが、内部的にはプレーンなJavaScriptオブジェクトに変換されます。配列でラップせずに、関数から2つのオブジェクトを返すことはできません。これは、別のタグまたはフラグメントでラップせずに2つのJSXタグを返すことができない理由でもあります。
2. すべてのタグを閉じる (リンクアイコン)
JSXでは、タグを明示的に閉じる必要があります。 <img>
のような自己終了タグは <img />
になり、 <li>oranges
のようなラップタグは <li>oranges</li>
と記述する必要があります。
ヘディ・ラマーの画像とリスト項目は、このように閉じられています。
<>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
/>
<ul>
<li>Invent new traffic lights</li>
<li>Rehearse a movie scene</li>
<li>Improve the spectrum technology</li>
</ul>
</>
3. すべて ほとんどのものをキャメルケースにする! (リンクアイコン)
JSXはJavaScriptに変換され、JSXで記述された属性はJavaScriptオブジェクトのキーになります。独自のコンポーネントでは、多くの場合、これらの属性を変数に読み込みたいと思うでしょう。ただし、JavaScriptには変数名に制限があります。たとえば、変数名にダッシュを含めたり、 class
のような予約語を使用したりすることはできません。
このため、Reactでは、多くのHTMLおよびSVG属性はキャメルケースで記述されます。たとえば、 stroke-width
の代わりに strokeWidth
を使用します。 class
は予約語であるため、Reactでは、対応するDOMプロパティ にちなんで、代わりに className
と記述します。
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
className="photo"
/>
DOMコンポーネントのプロップのリストで、これらの属性をすべて見つけることができます。 間違えた場合でも、心配しないでください。Reactはブラウザコンソールに、考えられる修正を含むメッセージを出力します。
プロのヒント:JSXコンバーターを使用する (リンクアイコン)
既存のマークアップでこれらの属性をすべて変換するのは面倒な場合があります!既存のHTMLおよびSVGをJSXに変換するには、コンバーター を使用することをお勧めします。コンバーターは実際には非常に便利ですが、JSXを自分で快適に記述できるように、何が起こっているのかを理解しておく価値はあります。
最終結果はこちらです
export default function TodoList() { return ( <> <h1>Hedy Lamarr's Todos</h1> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" className="photo" /> <ul> <li>Invent new traffic lights</li> <li>Rehearse a movie scene</li> <li>Improve the spectrum technology</li> </ul> </> ); }
まとめ (リンクアイコン)
JSXが存在する理由と、コンポーネントでJSXを使用する方法がわかりました。
- Reactコンポーネントは、レンダリングロジックとマークアップを関連付けているため、まとめてグループ化します。
- JSXはHTMLに似ていますが、いくつかの違いがあります。必要に応じて、コンバーター を使用できます。
- エラーメッセージは、多くの場合、マークアップを修正するための正しい方向を示しています。
いくつかの課題に挑戦してみましょう (リンクアイコン)
チャレンジ 1(of以下は文脈がないため翻訳できません) 1: HTMLをJSXに変換する
このHTMLはコンポーネントに貼り付けられましたが、有効なJSXではありません。修正してください。
export default function Bio() { return ( <div class="intro"> <h1>Welcome to my website!</h1> </div> <p class="summary"> You can find my thoughts here. <br><br> <b>And <i>pictures</b></i> of scientists! </p> ); }
手動で行うか、コンバーターを使用するかはあなた次第です!