📝

React.FCとは何かの整理

に公開

はじめに

ChatGPTでReactのコーディングをしている際に、

import React from 'react';

interface Props {
  ...
}

const Component: React.FC<Props> = ({...}) => {
  return (
    <>
      ...
    </>
  );
};

みたいな記述がたまに見られ、気になったので調べることにしました。

React.FCとは

React.FC(Function Component)は、ジェネリクス型と呼ばれるものです。

※ジェネリクス型:型も変数のように扱えるようにしたもの

React.FCでは、関数コンポーネントが受け取るpropsを指定できるという特徴があります。

React.FCのメリット

  1. コンポーネントが受け取るpropsに対して型安全性を提供できる。
    開発者が意図したデータ型のみを扱い、型エラーのコンパイルがしやすくなります。
    これにより、バグの早期発見に役立ち、コードの理解もしやすくなるというメリットがあります。

例:propsに型をつけない場合

const Greeting = ({ name }) => {
  return <h1>Hello, {name.toUpperCase()}</h1>;
};

// 呼び出し側
<Greeting name={123} />  // ← 数字を渡してもエラーにならない

この場合、実行時に123.toUpperCase()が呼び出されてエラーが発生する。
(JavaScriptだと実行するまでエラーが分からない)

例:propsに型をつけた場合(React.FCでもprops型直書きでもOK)

type GreetingProps = { name: string };

const Greeting: React.FC<GreetingProps> = ({ name }) => {
  return <h1>Hello, {name.toUpperCase()}</h1>;
};

// 呼び出し側
<Greeting name={123} />  // ❌ TypeScript がコンパイルエラーを出す
<Greeting name="Alice" /> // ✅ これは問題なく通る

型を明示的にすることで、間違った型を渡した瞬間にエラーが出るため、実行前にエラーに気づくことができます。これにより、

  • バグの早期発見
  • props型の可視化によるコード理解
    といった恩恵を受けることができます。

  1. コンポーネントのpropsのリファクタリングがしやすい。
    例えば、あるpropsの名前を変更したくなったとします。
    この場合、TypeScriptのコンパイラがそのpropsを使用している箇所を検出してくれるので、リファクタリングがしやすくなります。

たとえば、下記の例を考えてみます。

変更前

type GreetingProps = { name: string };

const Greeting: React.FC<GreetingProps> = ({ name }) => (
  <h1>Hello, {name}</h1>
);

// 呼び出し側
<Greeting name="Alice" />
<Greeting name="Bob" />

このnameというpropsを、userNameにリファクタリングしたくなったとします。

変更後

type GreetingProps = { userName: string };

const Greeting: React.FC<GreetingProps> = ({ userName }) => (
  <h1>Hello, {userName}</h1>
);

変更後では、変更前の呼び出し例はすべてエラーとして検出されます。

<Greeting name="Alice" />  // ❌ name はもう存在しない
<Greeting name="Bob" />    // ❌

このように、TypeScriptが「この呼び出しは間違っているよ」と全部自動で検出してくれるので、
呼び出すpropsを安心して一括置換することができます。

もし、この機能がなかったら、プロジェクト内のname=ctrl+Fとかでgrepしながら手直しする必要があるため、そこで人為的なミスが生じる可能性が出てしまいます。


  1. 型定義を見るだけで、そのコンポーネントがどのようなpropsを想定しているか分かりやすい
    React.FCを使って下記のようなコードを書いたとします。
type GreetingProps = {
  name: string;
};

const Greeting: React.FC<GreetingProps> = ({ name, children }) => (
  <div>
    <h1>Hello, {name}</h1>
    {children}
  </div>
);

この場合、このコードを見た人は

  • Greetingコンポーネントは、name:stringを必須で受け取る
  • childrenも受け取ることができる

という2つの情報が形定義を見るだけで分かるようになります。

最近のReact(19)では使わない書き方が主流?

React18より前のバージョンでは、React.FCに暗黙的にchildrenが含まれていたようです。
ところが、React18からは暗黙的にchildrenが含まれなくなったみたいです。

自分は個人的に学習をしているため、React.FCをどう使うか?と言った細かい部分までは突き詰めていませんでした。
ですが、チーム単位でReactのWebアプリケーション開発などを進めていく場合は、チーム内の方針などによって使い方が変わってくるかと思います。

参考

https://dev.to/elhamnajeebullah/react-typescript-what-is-reactfc-and-why-should-i-use-it-4029
https://typescriptbook.jp/reference/generics

Discussion