当サイトは、アフィリエイト広告を利用しています

【React】JSX記法の使い方

作成日:2022月02月21日
更新日:2023年12月21日

当ブログはReactのフレームワークのGatsbyで作成している。
Reactで使われるJSX記法についてブログ作成時、独学で学んだ中で
要点だと思ったことを忘備録として残す

その前にReactの画面描写の仕組みから知りたいという方は
下記記事で描写の仕組みをまとめています。

JSX記法って何?どれ?

イメージ的には、下記の return()の中が jsx記法 のイメージ。
{}の中ではjs部分(returnより上)で定義した変数や関数を使用することができる。

jsx
const HogeButton = ({ primary, label }) => {
return (
<button>
{primary
? <div className='primaryButtonInner'>{label}</div>
: <div className='normalButtonInner'>{label}</div>
}
</button>
)
}

jsx の基本

return 内は一つのタグ内にすべて収める

一番外側の親要素は一つでないといけない。 ※エラーになる

jsx
const HogeButton = ({ primary, label }) => {
return (
<button>
{primary
? <div className='primaryButtonInner'>{label}</div>
: <div className='normalButtonInner'>{label}</div>
}
</button>
)
}

jsx内でネストしてreturnを書いた場合も一つのタグ内にすべて収める

jsx内でネストして即時関数を書いた場合なども返却用の配列などを使用して
一つの親タグ内に収まるようにする必要あり

jsx
export default function App() {
let song = ["すべてはFになる", "封印再度", "詩的私的ジャック"];
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{(() => {
//jsx内で即時関数を使う場合
//返却用配列
const items = [];
song.forEach(element => {
items.push(<div>{element}</div>)
});
//戻り値は一つのタグ内の入れる
return <div>{items}</div>;
})()}
</div>
);
}

変数宣言はできない

JSX内で変数定義や関数定義をすることはできない。   関数については即時関数であれば使うことができる

if 文は使えない

Reactが採用しているJSXではif文はかけない。 JSX内でif文を書きたい場合は4通りの方法がある。

  1. 即時関数
  2. 外部定義関数
  3. 条件付きレンダー
  4. 三項演算子

即時関数を使う

JSX内の即時関数内でIF文を書く

jsx
export const HogeButton = ({ title,flg }) => {
return (
<section className="h2_elem">
{/* 即時関数(returnは必須) */}
{(() => {
if ( flg === "1" ) {
return <p>hoge1</p>
} else {
return <p>hoge2</p>
}
})()}
</section>
)
}
export default function App() {
return (
<div className="App">
<HogeButton title={"bottun"} flg={"0"}/>
</div>
);
}

一つならいいかもしれないが、大分見づらい...
あまり使わない方が良さそう。

外部で定義した関数を使う

JS部分に関数定義しておき、JSX内で呼び出す方式。

jsx
// 関数を定義
const hogeFunc = (flg) => {
if (flg === "1") {
return <p>hoge1</p>;
} else {
return <p>hoge2</p>;
}
};
const HogeButton = ({ flg }) => {
return (
//
<section className="h2_elem">
{/* 外部で定義した関数を呼ぶ */}
{hogeFunc(flg)}
</section>
);
};
export default function App() {
return (
<div className="App">
<HogeButton flg={"1"} />
</div>
);
}

条件付きレンダーを使う

「&&」を使って条件付きレンダーで書く。
一番よく見かけるパターンなので基本はこのパターンを使うでいいと思う。

jsx
export const HogeButton = ({ flg }) => {
return (
//
<section className="h2_elem">
{/*条件付きレンダー */}
{flg === "1" && <p>hoge1</p>}
{flg !== "1" && <p>hoge2</p>}
</section>
);
};
export default function App() {
return (
<div className="App">
<HogeButton title={"bottun"} flg={"1"} />
</div>
);
}
  • || は 左辺が true なら左辺を返し、左辺が false なら右辺を返す
  • && は 左辺が true なら右辺を返し、左辺が false なら左辺を返す

三項演算子を使用する。

JSX内では三項演算子を使える。

jsx
export const HogeButton = ({ flg }) => {
return (
//
<section className="h2_elem">
{/*三項演算子 */}
{flg === "1" ? <p>hoge1</p> : <p>hoge2</p>}
</section>
);
};
export default function App() {
return (
<div className="App">
<HogeButton title={"bottun"} flg={"2"} />
</div>
);
}

for 文は使えない

if文と同様にJSX内でfor文を普通に書くとエラーになる。
JSX内でfor文を使うには下記の4つの方がある。

  1. 即時関数
  2. 外部定義関数
  3. map()メソッドを使う

即時関数を使う

if文と同様にJSX内に直接書きたい場合は即時関数を使う必要がある。

即時関数のテンプレート
//即時関数
(()=> {
//処理
})();

実際に書いてみる

jsx
export default function App() {
let song = ["すべてはFになる", "封印再度", "詩的私的ジャック"];
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{(() => {
//forを使うパターン
//返却用配列
const items = [];
for (let i = 0; i < 5; i++) {
items.push(<div>{song[i]}</div>);
}
return <div>{items}</div>;
// forEachを使うパターン
// //返却用配列
// const items = [];
// song.forEach(element => {
// items.push(<div>{element}</div>)
// });
// return <div>{items}</div>;
})()}
</div>
);
}
  • 即時関数を使う場合、即時関数内で返却用配列を作って、その中に値を詰めてreturnしてやる必要がある。
  • 返却用配列に値を詰める方法はfor文でもforEachでもいい。
  • おそらくJSX内(のどこで書いても)でreturnするときは戻り値を一つの親タグの中に収める必要がものと思われる

返却用配列を使わないダメなパターン

jsx
export default function App() {
let song = ["すべてはFになる", "封印再度", "詩的私的ジャック"];
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{(() => {
//forを使う
for (let i = 0; i < 5; i++) {
return <div>{song[i]}</div>;
}
// forEachを使う
// song.forEach(element => {
// return (<div>{element}</div>)
// });
})()}
</div>
);
}
  • 配列の最初の一つしか表示されない。

外部で定義した関数を使う

外部で関数を定義し、JSX内で呼ぶこともできる。 ただし外部関数でも戻り値は一つの親タグ内に収める必要あり。

jsx
//外部で関数を定義
export const novel = (novels) => {
 //表示用配列
const novelsArray = [];
novels.forEach((novel) => {
novelsArray.push(<div>{novel}</div>);
});
return <div>{novelsArray}</div>;
};
export default function App() {
let novels = ["すべてはFになる", "封印再度", "詩的私的ジャック"];
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{/* 外部で定義した関数を呼ぶ */}
{novel(novels)}
</div>
);
}

mapメソッドを使う

reactで一番見る形で個人的には一番シンプルでわかりやすい。
特に理由がない場合はこの書き方にする。

jsx
export default function App() {
let novels = ["すべてはFになる", "封印再度", "詩的私的ジャック"];
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{/* mapを使う */}
{
novels.map(novel=>
<div>{novel}</div>
)
}
</div>
);
}
  • mapの場合は戻り値が配列になるので、返却用の配列を作る必要はない。

ラムダ式(アロー関数)は使える

filterとmapを使用する場合は下記のようになる。

jsx
export default function App() {
let novels = ["すべてはFになる", "封印再度", "詩的私的ジャック"];
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{/* mapやfilter使う */}
{novels
.filter((nov) => nov !== "封印再度")
.map((novel) => (
<div>{novel}</div>
))}
</div>
);
}
  • filterとmapをメソッドチェーンしている。

テンプレート文字列

テンプレート文字列を使って下記のように書くことができる

jsx
export default function App() {
let novels = ["すべてはFになる", "封印再度", "詩的私的ジャック"];
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
{novels.map((novel) => (
{/*テンプレート文字列を使う */}
<div>{`森博嗣:${novel}`}</div>
))}
</div>
);
}

参考

新着記事

タグ別一覧
top