JSX の最上位要素はひとつ
JSX 要素を作成するとき、トップレベルの要素は 1 つだけにする必要があります。
次のコードでは、トップレベルに 2 つの p
要素が並んでいるのでエラーになります。
const MyComponent: React.FC = () => {
return (
<p>Hello</p>
<p>World</p>
)
}
これを解決するには、例えば次のようにルート要素として div
を配置します。
return (
<div>
<p>Hello</p>
<p>World</p>
</div>
)
もちろん、これはこれで動作するのですが、ルートに余計な div
要素が作られてしまうのを防ぎたいときは、次のように <>...</>
で囲います(これは <React.Fragment>
の省略記法です)。
return (
<>
<p>Hello</p>
<p>World</p>
</>
)
条件を満たすときのみ出力する
次のコードは、n > 0
を満たしたときに、後半の p
要素を表示します。
return <>
{n > 0 && <p>条件を満たしたよ</p>}
</>
JSX コードの中では、if
や for
といった値を返さない文 (statement) を記述することができません。
なので、出力を条件分岐させたいときは、この例のように、&&
や ||
のような演算子を駆使する必要があります。
JSX の {}
内に記述した式の評価結果が undefined
、null
、true
、false
のいずれかになった場合、{}
全体は 何も出力しない ことを表します。
true
の場合に何も表示されないのは直感的ではないと思うかもしれませんが、画面上に true
と表示されても困るし、まぁそんなものだと受け入れるしかないですね。
上記コードの例でいうと、n > 0
の部分が「偽」になった瞬間に {}
全体が false
として評価されるため、結果的に何も出力されないということになります。
if-else 出力
ある条件を満たしたときは A、満たさなかったときは B、と表示分けしたいときは、JavaScript の 三項演算子(?
と :
) を使います。
次のコードは、n
が偶数のときに Even
、奇数のときに Odd
と出力します。
{n % 2 == 0 ? 'Even' : 'Odd'}
オブジェクトのあるプロパティが未設定 (undefined
) のときに代替値を表示したいときは、ES2020 の Nullish Coalescing (??) を使うとシンプルに記述できます。
次の例では、movie
オブジェクトの genre
プロパティが設定されているときはその値を表示し、設定されていないときは 不明
と表示します。
{movie.genre ?? '不明'}
配列要素のループ出力
配列要素を forEach
風に繰り返し出力するには、map
メソッドを使用します。
初めて見るとウッとなりますが、React/JSX の世界ではこの書き方は一般教養。
慣れるしかありません。
const foods = [
{ id: 1, name: 'apples' },
{ id: 2, name: 'bananas' },
{ id: 3, name: 'lemons' },
]
const FoodList: React.FC = () => {
return (
<ul>
{foods.map((f) => (
<li key={f.id}>I like {f.name}</li>
))}
</ul>
)
}
このように要素を繰り返し出力する場合は、React が効率的な差分出力を行えるように、各要素に一意な key
プロパティ値を指定しなければいけないことに注意してください(参考: リストと key)。
これを忘れると、Each child in a list should have a unique "key" prop.
といった警告が出ます。
n 回のループ出力
ちょっとハック的ですが、n 回の繰り返しは次のように記述できます。
{[...Array(3)].map((_, i) => (
<p key={i}>{i}: Hello</p>
))}
[...Array(3)]
という部分で、[undefined, undefined, undefined]
というサイズ 3 の配列を作っておいて、各要素を map
でループ処理してます。
こんな書き方しかできないの?そうですか・・・
コメントを記述する
JSX コードの中では、JavaScript と同様のコメント記法が使えます。
<>
<div>
{
// 一行コメント
n > 0 && <p>Hello</p>
}
</div>
<div>
{/*
複数行にわたるコメントは、
こんな感じで記述できます。
*/}
</div>
</>
ユーザーコンポーネント名は大文字で始める
JSX コード内で使うユーザー定義コンポーネントの名前は、大文字で始めなければいけません。
小文字で始まる名前 (p
や div
)は、組み込みのコンポーネントとして予約されているので使えません。
なお、JSX 組み込みのコンポーネントは JSX.IntrinsicElements
として定義されており、200 近くのコンポーネントが定義されています。