【React】条件によって指定の要素で囲むことができる汎用コンポーネントを作る

  • React
  • Typescript

自分用のメモとして残していますが、JSX のコードは下記参考サイトとほとんど同じです。英語ですが詳しい解説もあります(英語がそこまで読めないのでよく分かってない)

https://blog.hackages.io/conditionally-wrap-an-element-in-react-a8b9a47fab2

「特定の条件で a タグで囲みたい」などの時に重宝するコンポーネントです。

コンポーネント

冒頭で紹介したサイトを参考にしながら、Typescript を使いたいので tsx で作ります。

ConditionalWrapper/index.tsx

import React from 'react';

export interface IConditionalWrapperProps {
  condition: boolean;
  wrapper: (children: React.ReactNode) => JSX.Element;
  children: React.ReactNode;
}

export const ConditionalWrapper = ({ condition, wrapper, children }: IConditionalWrapperProps) => {
  return <>{condition ? wrapper(children) : children}</>;
};

props の説明

  • condition … 条件
  • wrapper … JSX。ここで受け取れる children は ConditionalWrapper で囲んだ要素。condition が true の時にラップされる。

とてもスマートです。

実際の例:特定の条件で a タグで囲む

import { ConditionalWrapper } from 'ConditionalWrapper';

<ConditionalWrapper condition={!!link} wrapper={children => <a href={link}>{children}</a>}>
  <span>ハローワールド</span>
</ConditionalWrapper>

link プロパティが存在する場合、a タグで囲んだ上で href 属性に link に代入しています(!! を2つ付けているのは型的に真偽値にしたいため)。

もし link が存在していれば…

<a href="linkの中身">
  <span>ハローワールド</span>
</a>

もし link が存在しなければ…

<span>ハローワールド</span>

となります。

これを使えば、三項演算子でほとんど同じなのに無駄に長ったらしいコードを書かなくて済みます。便利ですね。