【React×Typescript】typeのPropsをジェネリックで定義して共通化する

この記事は約 6 分で読めます。

みなさんこんにちは!ヒロポンです!!

今回はC#ではなくて、React×Typescript系の記事を書こうかと思います!

その名も!【React×Typescript】typeのPropsをジェネリックで定義する。です。

C#ではジェネリックって結構おなじみなので、結構使うのですがJS上がりとかTypeScriptから学習を始めている人はジェネリックについてなじみのない人が多いのではないでしょうか?

ということで今回はReactのFunctionComponentでのPropsをTypeエイリアスで定義する際にジェネリックを使う方法について書いていきたいと思います!!

Reactでコンポーネントを2つ用意する

まずはこんな感じでコンポーネントを二つ用意しましょう。

  • 生徒コンポーネント
  • 教師コンポーネント

生徒コンポーネントは学年と名前を持っています。

教師コンポーネントは教える教科と名前を持っています。

詳しく見ていきましょう。

生徒コンポーネント

import React, {FC} from 'react';

const Student : FC = () => {
    return (
        <div>
            <h2>生徒コンポーネント</h2>
            <p>名前:</p>
            <p>学年:</p>
        </div>
    );
};

export default Student;

教師コンポーネント

import React, {FC} from 'react';

const Teacher : FC = () => {
    return (
        <div>
            <h2>先生コンポーネント</h2>
            <p>名前:</p>
            <p>教える教科:</p>
        </div>
    );
};

export default Teacher;

実行結果

この段階でApp.tsxを修正し実行すると下記のような感じになります。

import React from 'react';
import logo from './logo.svg';
import './App.css';
import Student from "./Components/Student";
import Teacher from "./Components/Teacher";

function App() {
  return (
    <div className="App">
      <Student/>
      <Teacher/>
    </div>
  );
}

export default App;

まだ値を投げていないので、何も表示されていません。

2つのコンポーネントで使う型を用意する

上記2つのコンポーネントでのPropに使う型はこんな感じで定義します。

生徒コンポーネント

type Props = {
    Name : string,
    Gakunen : number
}

教師コンポーネント

type Props = {
    Name : string,
    Kyouka : string
}

それぞれのコンポーネントで受け取れるようにする

でこのままだとPropsを定義しただけで、値を受け取れないです。

なので下記のようにして値を受け取れるようにします。

import React, {FC} from 'react';

type Props = {
    Name : string,
    Gakunen : number
}

const Student : FC<Props> = (props) => {
    return (
        <div>
            <h2>生徒コンポーネント</h2>
            <p>名前:{props.Name}</p>
            <p>学年:{props.Gakunen}</p>
        </div>
    );
};

export default Student;

こういう感じにすれば、このコンポーネントを使う際に引数を取れます。

こんな感じでコンパイルエラーが出るので、下記のように修正します。

    <div className="App">
      <Student Name={"鈴木"} Gakunen={3}/>
      <Teacher/>
    </div>

とりあえずこれで実行すると下記のようになります。

教師コンポーネントも同じようにしておきます。

const Teacher : FC<Props> = (props) => {
    return (
        <div>
            <h2>先生コンポーネント</h2>
            <p>名前:{props.Name}</p>
            <p>教える教科:{props.Kyouka}</p>
        </div>
    );
};
      <Teacher Name={"田中"} Kyouka={"数学"}/>

実行結果

生徒と教師Propsを型付けする

で今後ジェネリックを使うにあたり、生徒と教師Propsを型付けしましょう。

そしてそれらの型を引数に受けるようにしましょう。

こんな感じでTypesフォルダを切って

export type StudentType = {
    Name : string,
    Gakunen : number
}

export type TeacherType = {
    Name : string,
    Kyouka : string
}

中身はこんな感じ

で、関係する箇所を直していきます。

type Props = {
    Data : TeacherType
}

const Teacher : FC<Props> = (props) => {
    return (
        <div>
            <h2>先生コンポーネント</h2>
            <p>名前:{props.Data.Name}</p>
            <p>教える教科:{props.Data.Kyouka}</p>
        </div>
    );
};
type Props = {
    Data : StudentType
}

const Student : FC<Props> = (props) => {
    return (
        <div>
            <h2>生徒コンポーネント</h2>
            <p>名前:{props.Data.Name}</p>
            <p>学年:{props.Data.Gakunen}</p>
        </div>
    );
};
    <div className="App">
      <Student Data={{Name : "鈴木",Gakunen : 3}}/>
      <Teacher Data={{Name : "田中",Kyouka : "数学"}}/>
    </div>

実行結果は変わりません。

型をジェネリックで定義する

でここで見えてきたのが、生徒と教師でのPropsにはDataというものがあって型が違うだけです。

この辺でジェネリックを使うことで共通化できます。

export type CommonProps<T> = {
    Data : T
}

こんな感じのPropsを定義して、それぞれのコンポーネントのPropsの型受け部分をこんな感じにします。

const Student : FC<CommonProps<StudentType>> = (props) => {
const Teacher : FC<CommonProps<TeacherType>> = (props) => {

これで実行すると

コンパイルエラーが起こらず出力できましたーー!!

今回のソースはGithubに上げています!

今回サンプルで作ったソースはGithubに「002_react_props_generic」というフォルダ名で上がっています!

ローカルにクローンを作っていろいろ試してみてください!

https://github.com/adaman3568/blog-source-demo

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA