React で JSX を利用すると、ビューの構築を HTML ライクな構文で組めます。
その中で、よくあるケースとして URL の有無によってアンカー(a)タグで要素全体をラップするか否かを判定して出力したい場合があります。
このように React の JSX で条件分岐して要素をラップする場合は、以下の方法で対応できます。
方法1 : 先にコンテンツをまとめておく(変数化)
例えば、リンク(URL)の指定があればアンカータグでラップしたい要素を予め変数に代入しておき、最後にリンクの有無をチェックして指定があれば、アンカー(JSX)で変数をラップします。
サンプルコード
// ラップする要素(アンカーで括る前のコンテンツ)を変数に代入
const component = (
<figure className={ this.props.className }>
<img src={ this.props.imageUrl }>
<figcaption>
{ this.props.caption }
</figcaption>
</figure>
)
// URL があればアンカータグで括る
if ( this.props.url ) {
return (
<a
href={ this.props.url }
className='image-anchor'
rel={ this.props.newTab ? 'noopener noreferrer' : undefined }
>
{ component }
</a>
)
}
return component
方法2 : コンポーネント化して利用する(汎用的)
より汎用的に、かつ JSX として視覚的に可読性が高い方法としては、条件分岐をコンポーネント化してしまうことです。
conditional-wrapper.jsラップ判定用の js
const ConditionalWrapper = ( { condition, wrapper, children } ) => condition ? wrapper(children) : children
export default ConditionalWrapper
このコンポーネント化した ConditionalWrapper は、以下のように利用します。
ビュー用の js
// conditional-wrapper.js をロード
import ConditionalWrapper from '/components/conditional-wrapper';
// ... なんやかんや色んな処理 ...
// ConditionalWrapper で括る
<ConditionalWrapper
condition={ this.props.url } // 条件(URLの有無)
wrapper={ children => ( // URLがあればアンカータグで括る
<a
href={ this.props.url }
className='image-anchor'
rel={ this.props.newTab ? 'noopener noreferrer' : undefined }
>
{ children }
</a>
) }
>
// ラップする要素
<figure className={ this.props.className }>
<img src={ this.props.imageUrl }>
<figcaption>
{ this.props.caption }
</figcaption>
</figure>
</ConditionalWrapper>
この方法であれば、条件分岐のチェックを conditional-wrapper.js にまとめておき、必要な箇所で import してコンポーネント化した ConditionalWrapper を用いて、ラップする条件(condition)とラッパー要素(wrapper)を指定するだけで要件を満たせます。


