コンポーネントをくっつける

これは私の好きな手です。Shopifyとかがやってたテクで、私は外国の方のコード見て「かっこいいな!」って思った。他にはRadix UIとかみたいな。それをパクりました。 あるFCコンポーネントにプロパティをくっつけたり、あるいはオブジェクトとしてまとめてエクスポートします。

Card.Header = CardHeader;
Card.Body = CardBody;
Card.Divider = Divider;
Card.Footer = CardFooter;

export { Card };

私のソースコードから抜粋しますが、こんな感じに好きなパーツを取り出して書くことが出来るんですよ。直感的な気がしていて、この考え方は私のお気に入りです。

export const EditArea = () => {
  const { imageFile } = useImageFile();
  if (imageFile === null) return null;

  return (
    <EditForm.Provider
      initialValue={{
        width: imageFile.width,
        height: imageFile.height,
        format: imageFile.format,
      }}
    >
      <motion.div
        initial={{ opacity: 0, y: 10 }}
        animate={{ opacity: 1, y: 0, transition: { duration: 0.3 } }}
      >
        <Card.Header className="px-6 flex justify-between gap-3">
          <FileName name={imageFile.name} />
          <EditMenu />
        </Card.Header>
        <Card.Divider />
        <EditForm.Form>
          <Card.Body className="flex px-6 my-2 justify-center items-center">
            <ImageView dataUrl={imageFile?.data_url} />
            <EditForm.Body />
          </Card.Body>
          <Card.Divider />
          <Card.Footer>
            <EditForm.SubmitButton />
          </Card.Footer>
        </EditForm.Form>
      </motion.div>
    </EditForm.Provider>
  );
};

ComponentProps

これも好きな手です。ReactにはComponentPropsないし、ComponentPropsWithRef, ComponentPropsWithoutRefって型があります。 特定のコンポーネントのPropsの型を持ってこれるってものですね。これも海外の人のリポジトリ漁ってて学んだんだけど、意外と知名度低い気がするんですよね、、 以下に私のソースコードの例を示します。

export interface ThemeButtonProps {
  variant?: ComponentProps<typeof Button>["variant"];
  size?: ComponentProps<typeof Button>["size"];
  invisibleRing?: boolean;
}

上記の場合、一部のプロパティに他のコンポーネントのPropsを共通に使いたくて持ってくるやり方なんですが、もっと汎用的な方法があって、inputとかdivみたいな一般的なHTMLタグのラッパーコンポーネントをfowardRefとかでくるむときにComponentPropsを使ってPropsの型を継承すれば、簡単に全部のタグのPropsを使えるようになります。ref使わないならComponentWithoutRefとかにもできる。 なぜfowardRefが必要かと言うと、特にサードパーティのライブラリとかでちょっとしたアニメーションとかついてる場合に、refが必要なケースって多いんですよね。そういうときに対応できるようなコンポーネントを作れておくと、ワカランって幅が少なくなる気がします。