0
1

propsでタグとなる文字列を受け渡して動的にHTMLタグを生成するコンポーネントを作り方

Last updated at Posted at 2023-12-05

propsでタグとなる文字列をpropsで渡して、HTMLタグとしてレンダリングするコンポーネントの作り方を紹介します。

TypeScriptやReactを学び始めて間もない方にオススメの内容だと思っております!

【結論】利用したいタグを直接渡せるようにする

私のような初心者はコンポーネントを作成する時に下記のような作り方をしてしまいます。

import React, { FC } from 'react';

type Props = {
  ordered?: boolean;
};

const List: FC<Props> = ({ ordered }) => {
  const ListTag = ordered ? 'ol' : 'ul';

  return (
    <ListTag>
      <li>listItem</li>
      <li>listItem</li>
    </ListTag>
  );
};

export default List;

別に悪くないとは思いますが…微妙だと思う点が2点あります。

  • orderedという余計なpropsを増やしてしまっている
  • 変数に入れるワンクッションが少し煩わしく感じる

今の仕様だとulol`どちらかしか入らないにもかかわらず、orderedというpropsを必要とすることを知らないと使えないコンポーネントとなってしまっているのがスマートではありません…。

下記のようにコードを修正してみます。

import React, { FC } from 'react';

type Props = {
  as: 'ul' | 'ol';
};

const List: FC<Props> = ({ as: Tag }) => {
  return (
    <Tag>
      <li>listItem</li>
      <li>listItem</li>
    </Tag>
  );
};

export default List;

asというpropsを定義し、ulとolが必ず入るようにリテラル型にしました。
さらにpropsで渡された値をTagに代入して利用できる形にしました。

asを必須の値と設定していますが「?」をつけることで任意の値とした上で、propsにデフォルトの値を設定することも可能です!

type Props = {
  as?: 'ul' | 'ol';
};

const List: FC<Props> = ({ as: Tag = 'ul' }) => {

asってなんだ?

asプロパティは、ReactのコンポーネントがレンダリングするHTMLタグを指定するためのものです。
なので先ほどのpropsのtype定義をstringに変更するとエラーになります。

type Props = {
-  as?: 'ul' | 'ol';
+  as?: string
};

// エラー内容
'Tag'  JSX コンポーネントとして使用することはできません
Its type 'string | undefined' is not a valid JSX element type.
 'undefined' を型 'ElementType' に割り当てることはできません

HTMLタグの名前しか受け取れないはずのasプロパティに対してstring、任意の文字列を許容する形式に変えたことでHTMLタグとして認知できない文字列を渡せてしまうためエラーとなります。

【propsでタグとなる文字列を受け渡して動的にHTMLタグを生成するコンポーネントを作り方】まとめ

propsでタグとなる文字を受け渡す場合はasプロパティを使うことで安全なコンポーネントかつシンプルな記述を実現できます!

コンポーネントの性質によりますが、実装方法として覚えておくと便利だと思います!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1