結論から
返り値として1つの式を返す必要があるためです。
if
文は式ではなく文ですので、そのままJSXのreturn 内で使うことはできません。
JSXと条件分岐
JSX とはReactでも採用されているJavaScriptの拡張構文であり、JavaScriptにHTMLのタグのようなマークアップを記述することができます。
JSXでは、return内の条件分岐は主に論理積演算子&&
や三項演算子? :
によって表されることが多いですが、これはどちらも条件分岐を式で表現できる点でif
とは異なります。
論理積演算子&&
による条件分岐
function App() {
const random = Math.random();
return (
<div>
{random >= 0.5 && (<div>{random} is greater than or equal to 1/2</div>)}
</div>
);
}
export default App;
&&
や?:
による条件分岐で条件部分が表示されていないのは、JSX がboolean やundefined
、null
を表示しないように無視するためです。
{0 && (<div>No Display</div>)}
のように書くと0
が表示されてしまいますので!!
をつけてbooleanに変換するなど対応が必要です。
if をreturn 内で使うには
どうしてもif
文を使用したいという場合には、(()=>{if文})
というような関数をreturn
内で実行することで式を返すようにすることで、if
の使用が可能になります(即時関数)。
function App() {
const random = Math.random();
return (
<div>
{(() => {
if (random >= 0.5) {
return <div> {random} is greater than or equal to 1/2</div>;
} else {
return <div> {random} is less than 1/2 </div>;
}
})()}
</div>
);
}
export default App;
if
を使用することはできていますが上の例では三項演算子を利用する方が可読性は上がりますね。
{random >= 0.5 ? (
<div> {random} is greater than or equal to 1/2</div>
) : (
<div> {random} is less than 1/2 </div>
)}
分岐が多い場合にはswitch
文なども使用することができます。
文であっても、式を返すようにすれば使用可能になります。
function App() {
const random = Math.random();
return (
<div>
{(() => {
const value = Math.floor(random * 4)
switch (value) {
case 0:
return <div>{`0 <= ${random} < 0.25`}</div>;
case 1:
return <div>{`0.25 <= ${random} < 0.5`}</div>;
case 2:
return <div>{`0.5 <= ${random} < 0.75`}</div>;
case 3:
return <div>{`0.75 <= ${random} < 1`}</div>;
default:
return null;
}
})()}
</div>
);
}
export default App;
if
やswitch
を使用しなければ分岐が煩雑になってしまうような場合には、return
の外側にロジックを移すことをおすすめします。
JSX では式を1つしか返せない
function App() {
return(
<div>a</div>
<div>b</div>
)
}
上のように2つの要素を返そうとするとエラーが出てしまいます。
これも返り値は1つの式しか認められていないために起きるエラーです。
返り値を1つの式とするために、<Fragment>
(<></>
)で要素を囲って返す必要が出てくるわけです。
JavaScriptでの返り値が1つでなくてはならないことと同じ制約ですね。
JSXに関する余談: サニタイズ
JSX の{}
構文には、式が自動でエスケープ処理される機能がついています。
XSS脆弱性などを含まないように、React
が自動で文字列をサニタイズ(消毒)してくれます。
dangerouslySetInnerHTML
属性によってエスケープ処理をせずに文字列をセットすることも可能ですが、XSS脆弱性を含まないように注意する必要があります。