【React】JSX 中で多重の分岐をインラインで書きたい時、三項演算子を使わずに分岐させる方法

  • 2022年7月5日
  • 2022年7月11日
  • React

 React でレンダリングする要素を定義する部分は JSX で記述され、JSX内ではしばしば三項演算子を使ってに分岐の制御をすることがあります。例えば次です。

import React from 'react';
export const PageLink = ({ mode }) => {
  return mode === 'UPDATE' ? '更新ページリンク' : '作成ページリンク';
};

 props で渡された mode の値によって表示されるリンクを変えるという例です。これぐらいならばまだスッと理解できるサイズなのでよいのですが、一つの分岐で扱うコンポーネントが増え、三項演算子がネストしだすとなかなか辛いものがあります。分岐内が一行で済んでいるので多少不適切ですが、例えば次の様になります。

import React from 'react';

export const PageLink = ({mode}) => {
  return mode === 'UPDATE' ? (
      '更新ページリンク'
    ) : mode === 'CREATE' ? (
      '作成ページリンク'
    ) : (
      '詳細ページリンク'
    );
};

 こういった時は Map を使うことで比較的シンプルに書けます。
Map – JavaScript | MDN

import React from 'react';

export const PageLinkWithMap = ({ mode }) => {
  return (
    // mode === key で分岐。コメントで何をキーにしているのか書くのを推奨
    // ここでコメントを書かないと JSX のかなり下の方を見に行く必要がある
    new Map([
      ['UPDATE', '更新ページリンク'],
      ['CREATE', '作成ページリンク'],
      ['SHOW', '詳細ページリンク'],
    ]).get(mode) || 'フォールバックリンク'
    // ↑は ?? がJSFidle で動かなかったので || にしていますが ?? でも行けます
  );
};

 Map はキーと値の対応を保持する JavaScript 組み込みオブジェクトです。これを使うことで二股の分岐が n – 1 回繰り返されるところ、一つのn股分岐にできます。これにより最後の else や else if にたどり着くまでの条件を頭の中に残す必要がなくなります。
 この書き方の欠点として書ける条件が単純なイコール止まりという点があります。あまり複雑な場合はそもそも JSX 内に分岐を書かずにおいた方がよいですが、m > n みたいな単純な比較の時は歯がゆい思いをします。

 余談としてオブジェクトでも次の様に似たことをできますが、事故を起こしやすいので Map を使った方が安全です。

export const PageLinkWithObject = ({mode}) => {
    return (
        // mode === 'toString' や mode === 'constructor' の時、
        // 真っ白になります。多分 function はレンダリングできないとかそんな感じです
        ({
            'UPDATE': '更新ページリンク',
            'CREATE': '作成ページリンク',
            'SHOW': '詳細ページリンク',
        })[mode] || 'フォールバックリンク'
    );
};

2022年7月11日追記:
排他的な条件ならば(二つ以上同時にtruthyになる場合がないならば)次の様に && を連続させるのも頭に覚えておくことが少なくて楽です。ただ falsy な部分に 0 等の文字列として表示可能なものが入ると余分なものが見えてしまうのでそれも注意です。

import React from 'react';

export const PageLink = ({ mode }) => {
  return (
    <>
      {mode === 'UPDATE' && '更新ページリンク'}
      {mode === 'CREATE' && '作成ページリンク'}
      {mode === 'SHOW' && '詳細ページリンク'}
    </>
  );
};
>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG