MochiuWiki : SUSE, EC, PCB
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Reactの基礎 - JSXの基本構文のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Reactの基礎 - JSXの基本構文
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == JSX (JavaScript XML) は、JavaScript内でHTMLライクなマークアップを記述するためのシンタックス拡張である。<br> ReactはJSXを用いることで、UIの構造をJavaScriptコードと同じファイル内に直感的に表現できる。<br> <br> JSXはWebブラウザがそのまま解釈できるわけではなく、BabelやTypeScriptコンパイラ等のトランスパイラによって、JavaScriptの関数呼び出しに変換される。<br> 変換後のコードは最終的にDOMを操作するReactの関数呼び出しとなる。<br> <br> 主な特徴は以下の通りである。<br> * JavaScript内にHTMLライクなマークアップを記述できる。 * 波括弧 <code>{}</code> を使用してJavaScript式を埋め込める。 * HTML属性名とは異なるcamelCaseベースの属性名を使用する。 * React 17以降では <code>import React from 'react'</code> の記述が不要になった。 * TypeScriptと組み合わせる場合は、<u>.tsx拡張子</u> のファイルを使用する。 <br><br> == JSXとは == JSXはJavaScriptのシンタックス拡張であり、JavaScript内でHTMLライクなマークアップを記述することを可能にする。<br> JSX自体はJavaScriptの仕様ではなく、トランスパイラによる変換を前提とした構文である。<br> <br> ==== JSXの変換の仕組み ==== React 16以前では、JSXはBabelによって <code>React.createElement()</code> 関数の呼び出しに変換されていた。<br> そのため、JSXを使用する全てのファイルで <u>import React from 'react'</u> の記述が必須だった。<br> <br> JSXと変換後のコードの対応例を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> // JSXによる記述 const element = <h1 className="greeting">Hello, World!</h1>; // Babelによる変換後 (React 16以前) const element = React.createElement( 'h1', { className: 'greeting' }, 'Hello, World!' ); </syntaxhighlight> <br> <code>React.createElement()</code> は第1引数にタグ名または関数コンポーネント、第2引数に属性のオブジェクト、第3引数以降に子要素を受け取る。<br> <br> 子要素が複数ある場合は、以下のように第3引数以降に続けて渡される。<br> <br> <syntaxhighlight lang="javascript"> // JSXによる記述 const element = ( <div className="container"> <h1>Title</h1> <p>Description</p> </div> ); // Babelによる変換後 (React 16以前) const element = React.createElement( 'div', { className: 'container' }, React.createElement('h1', null, 'Title'), React.createElement('p', null, 'Description') ); </syntaxhighlight> <br><br> ==== React 17以降の新しいJSXトランスフォーム ==== <u>React 17から、新しいJSXトランスフォームが導入された。</u><br> <u>この変換では、<code>React.createElement()</code> の代わりに <code>react/jsx-runtime</code> から <code>_jsx</code> 関数が自動的にインポートされる。</u><br> <br> 新しいJSXトランスフォームによる変換例を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> // JSXによる記述 (import Reactの記述が不要) function App() { return <h1>Hello, World!</h1>; } // コンパイラによる変換後 (React 17以降) import { jsx as _jsx } from 'react/jsx-runtime'; function App() { return _jsx('h1', { children: 'Hello, World!' }); } </syntaxhighlight> <br> 下表に、新しいJSXトランスフォームの変更点を示す。<br> <br> <center> {| class="wikitable" |+ 新しいJSXトランスフォームの主な変更点 ! 変更点 |- | <code>import React from 'react'</code> の記述が不要になった。 |- | JSXファイルに <code>React</code> 変数が存在しなくてもコンパイルエラーが発生しない。 |- | <code>react/jsx-runtime</code> からの自動インポートはバンドルツールが処理する。 |} </center> <br><br> == JSXにおける式の埋め込み == <u>JSXでは、波括弧 <code>{}</code> を使用してJavaScript式を埋め込むことができる。</u><br> <u>これは、テキスト部分と属性値の両方で使用できる。</u><br> <br> ==== 波括弧 {} の基本 ==== 波括弧を使用できる場所は2箇所ある。<br> <br> <center> {| class="wikitable" |+ 波括弧を使用できる場所 ! 場所 !! 例 |- | タグ内のテキスト部分 || <u><p>{expression}</p></u> |- | 属性値 || <u><img src={imageUrl} /></u> |} </center> <br> 変数、計算式、関数呼び出しの埋め込み例を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> const user = { name: 'Alice', age: 30, imageUrl: 'https://example.com/alice.jpg' }; function formatGreeting(name) { return `Hello, ${name}!`; } function UserCard() { return ( <div> {/* 変数の埋め込み */} <h1>{user.name}</h1> {/* 計算式の埋め込み */} <p>来年の年齢: {user.age + 1}</p> {/* 関数呼び出しの埋め込み */} <p>{formatGreeting(user.name)}</p> {/* 属性値への埋め込み */} <img src={user.imageUrl} alt={user.name} /> </div> ); } </syntaxhighlight> <br> ==== 埋め込み可能な式と不可能な文 ==== 波括弧内に記述できるのはJavaScriptの <u>式 (expression)</u> に限られる。<br> 値を返さない <u>文 (statement)</u> は直接埋め込むことができない。<br> <br> 下表に、埋め込み可能な式と埋め込み不可能な文の例を示す。<br> <br> <center> {| class="wikitable" |+ 式と文の比較 ! 分類 !! 例 !! 備考 |- | 変数参照 (式) || <u>{name}</u> || 変数の値が表示される。 |- | 文字列連結 (式) || <u>{'Hello, ' + name}</u> || 連結した文字列が表示される。 |- | 算術演算 (式) || <u>{price * quantity}</u> || 計算結果が表示される。 |- | 関数呼び出し (式) || <u>{formatDate(date)}</u> || 戻り値が表示される。 |- | 三項演算子 (式) || <u>{isLoggedIn ? 'ログイン中' : 'ログアウト'}</u> || 条件による切り替え |- | 論理演算 (式) || <u>{count > 0 && <span>{count}</span>}</u> || 短絡評価による条件付き表示 |- | プロパティアクセス (式) || <u>{user.name}</u> || オブジェクトのプロパティ参照 |- | if文 (文) || <u>{if (条件) { ... }}</u> || 埋め込み不可。三項演算子または論理演算を使用する |- | for文 (文) || <u>{for (let i ...) { ... }}</u> || 埋め込み不可<br><u>Array.map()</u> を使用する。 |- | while文 (文) || <u>{while (条件) { ... }}</u> || 埋め込み不可<br><u>Array.map()</u> 等を使用する。 |- | 変数宣言 (文) || <u>{const x = 1}</u> || 埋め込み不可<br>JSX外で宣言する。 |- | オブジェクト直接参照 (不可) || <u>{person}</u> || エラー<br><u>{person.name}</u> のようにプロパティを指定する。 |} </center> <br><br> == JSXの属性 == JSXの属性は、HTMLの属性と似た構文で記述するが、いくつかの重要な違いがある。<br> <br> ==== HTML属性との違い ==== JSXの属性名は基本的に <u>キャメルケース (camelCase)</u> を使用する。<br> ただし、<u>ARIA属性 (<code>aria-*</code>)</u> と <u>data属性 (<code>data-*</code>)</u> はハイフン区切りをそのまま使用する。<br> <br> 下表に、HTMLとJSXの属性名の対応を示す。<br> <br> <center> {| class="wikitable" |+ HTML属性とJSX属性の対応 ! HTML属性 !! JSX属性 !! 備考 |- | <code>class</code> || <code>className</code> || JavaScriptの予約語 <code>class</code> との衝突を避けるため |- | <code>for</code> || <code>htmlFor</code> || JavaScriptの予約語 <code>for</code> との衝突を避けるため |- | <code>tabindex</code> || <code>tabIndex</code> || camelCaseに変換 |- | <code>contenteditable</code> || <code>contentEditable</code> || camelCaseに変換 |- | <code>stroke-width</code> || <code>strokeWidth</code> || SVG属性もcamelCaseに変換 |- | <code>aria-label</code> || <code>aria-label</code> || ARIA属性はハイフン区切りを保持 |- | <code>data-testid</code> || <code>data-testid</code> || data属性はハイフン区切りを保持 |} </center> <br> ==== 属性値の指定方法 ==== JSXの属性値には、文字列リテラル、JavaScript式、スプレッド構文の3つの指定方法がある。<br> <br> <syntaxhighlight lang="javascript"> const attrs = { src: avatarUrl, alt: userName, width: 100 }; function Avatar() { return ( <div> {/* 文字列リテラル: クォートで囲む */} <img className="avatar" alt="ユーザアバター" /> {/* JavaScript式: 波括弧で囲む */} <img src={avatarUrl} alt={userName} /> {/* スプレッド構文: オブジェクトの全プロパティを展開 */} <img {...attrs} /> </div> ); } </syntaxhighlight> <br> 属性値の指定に関する注意点を以下に示す。<br> * <u>src="{avatarUrl}"</u> のようにクォート内で波括弧を使用すると、式ではなく文字列として渡される。 * 文字列と式を同時に指定する場合は、テンプレートリテラルを式として渡す。 *: <u>className={`button ${isActive ? 'active' : ''}`}</u> <br> ==== スタイルの指定 ==== JSXでは <code>style</code> 属性にJavaScriptオブジェクトを渡す。<br> HTMLのように文字列で指定することはできない。<br> <br> <syntaxhighlight lang="javascript"> function StyledComponent() { // スタイルオブジェクトを変数として定義する方法 const containerStyle = { backgroundColor: 'black', color: 'pink', padding: 20, // 数値はデフォルトで px 単位になる fontSize: '1rem' // 文字列で単位を指定することもできる }; return ( <div> {/* 変数を使用する方法 */} <div style={containerStyle}>コンテンツ</div> {/* インラインで直接指定する方法 (二重波括弧) */} {/* 外側の波括弧: JSX式、内側の波括弧: JavaScriptオブジェクト */} <p style={{ marginTop: 10, fontWeight: 'bold' }}>テキスト</p> </div> ); } </syntaxhighlight> <br> スタイル指定に関する重要な規則を以下に示す。<br> <br> * CSSプロパティ名は、<u>キャメルケース (camelCase)</u> で記述する。 *: <u>background-color</u> -> <u>backgroundColor</u> * 数値を指定した場合、デフォルトで <code>px</code> 単位が付与される *: <u>marginTop: 20</u> -> <u>margin-top: 20px</u> * <code>px</code> 以外の単位を使用する場合は文字列で指定する。 *: <u>width: '50%'</u> <br><br> == JSXのルール == JSXを正しく使用するために、いくつかの重要なルールがある。<br> <br> ==== 単一ルート要素 ==== JSXのコンポーネントから返す要素は、必ず1つのルート要素でラップする必要がある。<br> <br> この制約はJSXがJavaScriptオブジェクトに変換されることに起因する。<br> 1つの関数が複数の値を返せないのと同様に、JSXも1つのルート要素しか返せない。<br> <br> <syntaxhighlight lang="javascript"> // エラー : 複数のルート要素 function BadComponent() { return ( <h1>タイトル</h1> <p>説明文</p> ); } // 解決策1 : divでラップする function GoodComponent1() { return ( <div> <h1>タイトル</h1> <p>説明文</p> </div> ); } // 解決策2 : フラグメントでラップする (DOMに余分なノードが追加されない) function GoodComponent2() { return ( <> <h1>タイトル</h1> <p>説明文</p> </> ); } </syntaxhighlight> <br> ==== 全てのタグは閉じる必要がある ==== JSXでは、全てのHTMLタグを閉じる必要がある。<br> HTMLでは省略可能な自己閉じタグも、JSXでは明示的に閉じる必要がある。<br> <br> <syntaxhighlight lang="javascript"> function FormExample() { return ( <div> {/* 自己閉じタグは必ずスラッシュを付ける */} <img src="photo.jpg" alt="写真" /> <br /> <hr /> <input type="text" /> {/* コンテンツを持つタグは閉じタグが必要 */} <li>リスト項目</li> <p>段落テキスト</p> </div> ); } </syntaxhighlight> <br><br> == フラグメント == フラグメントは、DOMに余分なノードを追加せずに複数の要素をグループ化するための仕組みである。<br> <br> ==== React.Fragmentの基本 ==== フラグメントには短縮構文 <code><>...</></code> と 明示的な <code><React.Fragment>...</React.Fragment></code> の2つの記法がある。<br> <br> <syntaxhighlight lang="javascript"> import React from 'react'; function TableRows() { return ( <> {/* 短縮構文: DOMにノードが追加されない */} <tr> <td>行1のデータ1</td> <td>行1のデータ2</td> </tr> <tr> <td>行2のデータ1</td> <td>行2のデータ2</td> </tr> </> ); } function App() { return ( <table> <tbody> <TableRows /> </tbody> </table> ); } </syntaxhighlight> <br> フラグメントを使用するメリットを以下に示す。<br> <br> * 不要な <code>div</code> 要素の追加を避けられる。 * テーブルやフレックスボックスのレイアウトを壊さない。 * DOMのネスト構造をシンプルに保てる。 <br> ==== keyを持つフラグメント ==== <u>リストのレンダリング時等、フラグメントに <code>key</code> 属性を指定する必要がある場合は、短縮構文 <code><></code> を使用できない。</u><br> <u>この場合は <code>React.Fragment</code> を明示的にインポートして使用する。</u><br> <br> <syntaxhighlight lang="javascript"> import { Fragment } from 'react'; const items = [ { id: 1, title: '項目1', description: '説明1' }, { id: 2, title: '項目2', description: '説明2' }, { id: 3, title: '項目3', description: '説明3' }, ]; function ItemList() { return ( <dl> {items.map((item) => ( // key属性を持つフラグメントには React.Fragment を使用する <Fragment key={item.id}> <dt>{item.title}</dt> <dd>{item.description}</dd> </Fragment> ))} </dl> ); } </syntaxhighlight> <br> <code>key</code> 属性を持つフラグメントに関する注意点を以下に示す。<br> <br> * 短縮構文 <code><></></code> は <code>key</code> 属性を受け付けない。 * <code>Fragment</code> は <code>react</code> パッケージからインポートする必要がある *: <u>import { Fragment } from 'react'</u> * <code>key</code> 以外の属性はフラグメントに渡すことができない。 <br><br> == JSX と TypeScript (TSX) == <u>TypeScriptでReactを使用する場合、ファイルの拡張子を <code>.tsx拡張子</code> とすることでJSXが使用できる。</u><br> <u>ただし、ジェネリクス (型パラメータ) と JSXの構文が衝突する問題に注意が必要である。</u><br> <br> ==== 型パラメータとJSXの衝突 ==== アロー関数でジェネリクスを使用する場合、型パラメータの <code><T></code> がJSXのタグとして解釈されてしまう問題が発生する。<br> <br> <syntaxhighlight lang="typescript"> // エラー : <T> がJSXタグとして解釈される (.tsx ファイルの場合) const identity = <T>(value: T): T => value; // 解決策1 (推奨) : function宣言を使用する function identity<T>(value: T): T { return value; } // 解決策2 : 末尾カンマを追加する (TypeScriptコンパイラへのヒント) const identity = <T,>(value: T): T => value; // 解決策3 : extends を使用して型パラメータを制約する const identity = <T extends unknown>(value: T): T => value; </syntaxhighlight> <br> 各解決策の特徴を以下に示す。<br> <br> * function宣言を使用する方法が最も明確でTypeScriptの慣習に沿っており、推奨される。 * 末尾カンマ <code><T,></code> はTypeScriptコンパイラに型パラメータであることを示すが、ソースコードの可読性が落ちる場合がある。 * <code>extends</code> を使用する方法は型制約を意図していると誤解される可能性がある。 <br><br> == 関連情報 == * [[Reactの基礎 - TSXの基本構文]] * [[Reactの基礎 - 条件レンダリング]] * [[Reactの基礎 - リストレンダリング]] * [[Reactの基礎 - コンポーネント]] * [[Reactの基礎 - PropsとChildren]] <br><br> {{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板,React,JSX,JavaScript,TypeScript,TSX,Fragment,createElement,jsx-runtime,コンポーネント,フロントエンド |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux |image=/resources/assets/MochiuLogo_Single_Blue.png }} __FORCETOC__ [[カテゴリ:Rust]][[カテゴリ:Web]]
Reactの基礎 - JSXの基本構文
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse