再利用可能なコンポーネント作成

再利用可能なコンポーネント作成

投稿日: 2024年12月29日

Tips
学習振り返り
要約
  • 再利用可能なコンポーネントを作成することで、コードの可読性と安全性が向上する。
  • Buttonコンポーネントは、href、type、children、classNameをプロパティとして持ち、様々な用途に対応できる。
  • 再利用できるコンポーネントを意識することで、コード量を減らし、他のページでも簡単に活用できる。

はじめに

今まで、特定のコンポーネントのみを作ってきて、”再利用”という意味では使いにくいコンポーネントを作ってました!
昨日ぶべさんにご指摘してもらい、改めて調べて再利用の作り方を学んでコード量を少し減らせたことに成功しました!😎
今回は、再利用可能なコンポーネントの作成について書いていきます!

コンポーネント

コンポーネントとは、再利用可能な部品と理解してもらえたらいいと思います!
Webページで言うと、ヘッダー、メインコンテンツ、フッターとそれぞれの部品がWebページを構成要素となります。

再利用可能なコンポーネント作成|ShiftBブログ


再利用可能なコンポーネント

ポイント

  1. 型定義(ButtonProps)
    目的
    コンポーネントが受け取る”props”の型を明確に定義することで、コードの安全性を可読性を向上

    構成
    href:string;: リンク先のURLを指定。

    type: string;: HTMLの`<button>要素や<input>要素にはtype`属性があります。
    これにより、コンポーネント内で子要素を簡単に扱うことができます。

    children: React.ReactNode;: ボタン内に表示されるコンテンツ(テキストやアイコン)
    例えば、<button>ボタン</button>というタグで言うと、ボタンがprops.children になります。

    className: string;: ボタンにCSSクラスを指定して、スタイルカスタマイズが可能。
    これをつけることで、他のページでどんなパターンでもスタイルをカスタマイズできるので、あると便利!!

  2. Props
    Props(プロパティ)は、親コンポーネントから子コンポーネントにデータを渡すための仕組み。
    Propsを使うことで、コンポーネントの再利用を可能にし、動的データを変更できる!

    構成
    propsとしてhref, type. children, classNameを受け取り、それぞれの役割に応じてコンポーネント内で使用している。

//Button.tsx

"use client";
import React from "react";
import Link from "next/link";

type ButtonProps = {
  href: string;
  type: string;
  children: React.ReactNode;
  className: string;
};

export const Button: React.FC<ButtonProps> = ({ href, type, children, className }) => {

  return (
    <button className={className}>
    <Link href={href} type={type}>
    {children}
    </Link>
    </button>
  )
}


Buttonコンポーネント活用法

  1. ナビゲーションリンクとして使用
    Buttonコンポーネントは、ページ間のナビゲーションを行うためのリンクとして使用されます。hrefプロパティを指定することで、リンク先のURLを設定できる。

  2. スタイルカスタマイズ
    classNameプロパティを使用して、ボタンのスタイルをカスタマイズができるようになります。これで、異なるボタンのスタイルを他のページでも簡単に作成できます。

  3. コンテンツの柔軟性
    childrenプロパディを使用して、ボタン内に表示するコンテンツ(テキストやアイコン)を指定できる。

  4. フォーム送信ボタン
    typeプロパティを使用して、type="submit"を指定することで、フォームの送信ボタンとして機能することができる。

//signup.tsx
"use client";
import { supabase } from "@/utils/supabase";
import { useState } from "react";
import { Input } from "../_components/Input";
import { Label } from "../_components/Label";
import { HeaderBase } from "../_components/HeaderBase";
import { Button } from "../_components/Button";

const SignUp = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    const { error } = await supabase.auth.signUp({
      email,
      password,
      options: {
        emailRedirectTo: `${process.env.NEXT_PUBLIC_BASE_URL}/login`,
      },
    });

    if (error) {
      alert("登録に失敗しました");
    } else {
      setEmail("");
      setPassword("");
      alert("確認メールを送信しました");
    }
  };

  return (
    <div>
      <div className="w-full min-h-36 flex justify-between  px-10 h-15 bg-beige-200">
      <HeaderBase href="/" className="py-12">
        WorkBrew
      </HeaderBase>
      </div>
      <div className=" min-h-screen bg-tan-300 flex flex-col items-center justify-center">
        <form onSubmit={handleSubmit} className="w-full max-w-[500px] ">
          <div className="py-5">
            <Label htmlFor="email" className="block md-2">
              メールアドレス
            </Label>
            <Input
              type="email"
              name="email"
              id="email"
              className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-3xl focus:ring-blue-500 focus:border-blue-500 block w-full p-5"
              required
              onChange={(e) => setEmail(e.target.value)}
              value={email}
            />
          </div>
          <div className="py-5">
            <Label htmlFor="password" className="block md-2">
              パスワード
            </Label>
            <Input
              type="password"
              name="password"
              id="password"
              className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-3xl focus:ring-blue-500 focus:border-blue-500 block w-full p-5"
              placeholder="••••••••"
              required
              onChange={(e) => setPassword(e.target.value)}
              value={password}
            />
          </div>
          <div className="py-5 flex justify-center">
            <Button
              href="/"
              type="submit"
              className="w-[120px]  text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-3xl text-sm px-5 py-2.5 text-center"
            >
              登録
            </Button>
          </div>
        </form>
      </div>
    </div>
  );
};

export default SignUp;

おわり

再利用できるようなコンポーネント意識をすると、コード量が減り他のページでも利用ができるとても便利なもの!
積極的に使っていきましょう!

シェア!

Threads
記事一覧に戻る
Threads
0