黄昏の迷宮

知的好奇心を刺激する冒険

【React】コンポーネントにアイコンを渡す

React + Chakra UIでちょっとしたサイトを作っています。

Chakra UIに慣れようということでまず404ページを作成しました。

ホームに戻るアイコン部分は当然コンポーネント化したのですが、このままではホームに戻る専用なのでもう少し汎用的に使えるようにしたいと思いました。

import { Center, Icon, Text, VStack } from "@chakra-ui/react";
import { RiHomeLine } from "react-icons/ri";
import { Link } from "wouter";

function LinkIconHome() {
 return (
  <Link href="/" style={{ textDecoration: "none" }}>
   <Center>
    <VStack>
     <Icon>
      <RiHomeLine size="32" />
     </Icon>
     <Text fontSize="sm">Home</Text>
    </VStack>
   </Center>
  </Link>
 );
}

export default LinkIconHome;

ここでちょっと悩んだのがアイコンってどうやって渡せばいいんだろうということでした。

PropsでIconTypeを渡せばいけるのではないかと思ったりもしましたが、IconコンポーネントはReactNodeを受け取るので、IconTypeを渡すとエラーになってしまいます。

そこで、Iconコンポーネントの子要素としてアイコンを渡すことにしました。

これで汎用的に使えるようになりました。

import { Center, Icon, Text, VStack } from "@chakra-ui/react";
import type { ReactNode } from "react";
import { Link } from "wouter";

interface Props {
 path: string;
 label: string;
 size?: string;
 children: ReactNode;
}

function LinkIcon(props: Props) {
 return (
  <Link href={props.path} style={{ textDecoration: "none" }}>
   <Center>
    <VStack>
     <Icon>{props.children}</Icon>
     <Text fontSize={props.size ?? "sm"}>{props.label}</Text>
    </VStack>
   </Center>
  </Link>
 );
}

export default LinkIcon;

呼び出す側(抜粋)はこんな感じです。

import { RiHomeLine } from "react-icons/ri";
import LinkIcon from "@/components/LinkIcon";

<LinkIcon path="/" label="Home">
  <RiHomeLine size="32" />
</LinkIcon>

解決すれば簡単なことでしたが、Chidrenを使うことはなかなか思いつきませんでした。 まあ、こうした悩んだ時間は案外楽しいものですよね。