Reactの関数コンポーネント — 現代の開発標準

著者: IT Sectr 公開日: 2026-07-04 読了時間: 9 分

Functional Component — 通常のJavaScript関数を使ってReactコンポーネントを作成する方法で、React 16.8のリリースとフックの登場により標準となりました。関数コンポーネントはpropsを受け取り、React.Componentからの継承を必要とせずにReact要素を返します。React、2024によると、Reactエコシステムの97%の新規コンポーネントが関数として書かれています。

重要ポイント

  • Functional Component — extends Componentなしでpropsを受け取りJSXを返す、通常のJavaScript関数。
  • フック(useState、useEffect、useContext)は関数コンポーネントに状態とライフサイクルへの完全なアクセスを提供します。
  • 可読性 — 関数コンポーネントはクラスコンポーネントより短く、コンストラクター、bind、余分なライフサイクルメソッドが不要。
  • パフォーマンス — Reactはメモ化と遅延初期化を通じて関数コンポーネントを最適化します。
  • React推奨 — すべての新規プロジェクトはフック付きの関数コンポーネントのみを使用すべき。

関数コンポーネントとは?

関数コンポーネントは、propsオブジェクトを受け取りReact要素を返す関数として定義されたReactコンポーネントです。React 16.8以前は、内部状態を管理できなかったため、これらのコンポーネントはステートレスと呼ばれていました。

React 16.8(2019年2月)でのフックの導入により、関数コンポーネントは状態(useState)、副作用(useEffect)、コンテキスト(useContext)、ref(useRef)にアクセスできるようになりました。「ステートレス」という用語は時代遅れです — 現代の関数コンポーネントは状態を完全に管理します。

Reactは公式に関数コンポーネントをコンポーネント作成の主要な方法として推奨しています。react.devのすべてのドキュメント、例、チュートリアル、新しいAPI(Server Components、Actions)は関数型アプローチに基づいています。クラスコンポーネントは削除されていませんが、Reactの新機能はフックを通じてのみ利用可能です。

関数コンポーネントの作成

最も簡単な関数コンポーネントは、JSXを返す関数です。propsを引数として受け取り、コンストラクター、super呼び出し、thisバインディングは不要です。propsは関数の引数を通じて直接アクセス可能です — this.propsは不要です。

js
// Functional component without state
function Greeting({ name }) {
  return <h1>Hello, {name}!</h1>;
}

// Arrow function (common variant)
const Greeting = ({ name }) => (
  <h1>Hello, {name}!</h1>
);

状態を持つコンポーネント

状態を追加するにはuseStateを使用します。フックは現在の状態とセッター関数の2つの値を持つタプルを返します。クラスベースのthis.setStateとは異なり、useStateは前の値とマージするのではなく、値を完全に置き換えます。

js
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

関数コンポーネントのフック

フックは現代のReactの基礎です。各フックは特定のタスクを解決します:useState — 状態、useEffect — 副作用、useContext — コンテキストアクセス、useRef — DOM要素参照、useCallbackuseMemo — メモ化。

副作用のためのuseEffect

useEffectはcomponentDidMount、componentDidUpdate、componentWillUnmountを同時に置き換えます。最初の引数はエフェクトを持つコールバック、2番目は依存配列です。配列が空の場合、エフェクトはマウント後に1回実行されます。依存関係が指定されている場合、それらのいずれかが変更されるたびに実行されます。

js
import React, { useState, useEffect } from 'react';

function UserData({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    let cancelled = false;

    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => {
        if (!cancelled) setUser(data);
      });

    // Cleanup - analog of componentWillUnmount
    return () => { cancelled = true; };
  }, [userId]); // Dependency

  return <div>{user?.name}</div>;
}

カスタムフック

関数コンポーネントの主な利点は、カスタムフックによるロジックの再利用です。クラスコンポーネントではロジックがcomponentDidMountとcomponentDidUpdateで重複していましたが、関数コンポーネントではuseプレフィックスを持つ別の関数に抽出されます。カスタムフックはHOCやrender propsに代わる主要な方法です。

継承より合成

Reactはコンポーネント間のコード再利用に継承よりも合成を推奨しています。関数コンポーネントは合成に理想的です:1つのコンポーネントが複数の他のコンポーネントを含み、propsとchildrenを渡せます。

childrenパターン — コンポーネントがchildrenプロップを通じて子要素を受け取る — は自然に実装されます:function Layout({ children })。Vueのスロットに相当するものは、名前付きコンポーネントプロップを通じて実装されます:function Page({ header, sidebar, content })

継承はReactではほとんど使用されません。技術的にextendsをサポートするクラスコンポーネントでさえ、1階層より深い階層を形成することは稀です。合成を用いた関数コンポーネントは、継承なしでコード再利用のニーズを完全にカバーします。

パフォーマンス最適化

関数コンポーネントには組み込みの最適化メカニズムが備わっています。React.memo — 関数用のPureComponent相当:propsが変更されていない場合に再レンダリングを防ぎます(浅い比較)。useMemoはレンダリング間で計算結果をキャッシュします。

js
import React, { useMemo } from 'react';

// React.memo - memoize component
const ExpensiveList = React.memo(({ items }) => {
  return <ul>
    {items.map(item =>
      <li key={item.id}>{item.name}</li>
    )}
  </ul>;
});

// useMemo - caching result
function Dashboard({ transactions }) {
  const summary = useMemo(() => {
    return transactions.reduce((acc, t) => acc + t.amount, 0);
  }, [transactions]);

  return <p>Total: {summary}</p>;
}

useCallbackはコールバック関数をメモ化し、毎回のレンダリングで再作成されないようにします。これはReact.memoでラップされた子コンポーネントに関数を渡す際に重要です:useCallbackがないと、関数参照が変わるたびに子コンポーネントが再レンダリングされます。

関数型 vs クラス型コンポーネント

アプローチの違いは構文を超えています。関数コンポーネントはクロージャです:状態と効果は特定のレンダリングに結びついています。クラスコンポーネントはthisを使用します:状態は常にthis.stateから取得され、非同期コールバックの実行時には古くなっている可能性があります。

側面関数型クラス型
状態useState(独立)this.state + this.setState
効果依存関係付きuseEffectcomponentDidMount + componentDidUpdate
コンテキストuseContextContext.Consumerまたはstatic contextType
最適化React.memo + useMemoPureComponent + shouldComponentUpdate
ロジック再利用カスタムフックHOC / Render props
thisなしコンストラクターでbind

関数コンポーネントは線形な実行フローを提供します。クラスコンポーネントでは、関連するロジックが複数のライフサイクルメソッドに散らばることがよくあります。例えば、WebSocket購読はcomponentDidMountで設定され、componentWillUnmountで解除されます。関数コンポーネントでは、両方の操作がクリーンアップ関数を返す1つのuseEffectに含まれています。

TypeScriptと関数コンポーネント

TypeScriptはクラスよりも関数コンポーネントとより自然に連携します。Propsの型付け — 関数の引数に対するインターフェース。戻り値の型はJSX.ElementまたはReactNodeです。useStateは初期値から自動的に型を推論します。

ts
import React, { useState } from 'react';

interface ButtonProps {
  label: string;
  variant?: 'primary' | 'secondary';
  onClick: () => void;
}

const Button: React.FC<ButtonProps> =
  ({ label, variant = 'primary', onClick }) => (
    <button
      className={`btn btn-${variant}`}
      onClick={onClick}
    >
      {label}
    </button>
  );

現代のTypeScriptでは、判別共用体型でuseReducerを型付けしたり、カスタムフックでジェネリクスを使用したり、React.PropsWithChildrenを通じて子要素の厳密な検証が可能です。TypeScriptを用いた関数コンポーネントは、追加の抽象化なしで完全な型安全性を提供します。

よくある質問

なぜReactは関数コンポーネントを推奨するのですか?

関数コンポーネントはよりシンプルです:コンストラクター、bind、this、散在するライフサイクルメソッドがありません。フックは関連するロジックをグループ化できます。Reactはクラスではなくフックの開発にリソースを投資しています。Server Componentsや新機能は関数でのみ利用可能です。

関数コンポーネントでsetIntervalを使用できますか?

はい、useEffectを通じて、内部にタイマーとclearInterval用のクリーンアップ関数を配置します。クロージャに注意してください:カウンターを ticks させる場合、setStateの関数形式を使用します:setCount(c => c + 1) これにより、クロージャ内の古い値に依存することを避けられます。

関数コンポーネントで以前のpropsを取得するには?

以前の値を保存するにはuseRefを使用します。各レンダリング後にuseEffectでrefを更新します。カスタムフックusePreviousがクリーンな比較に役立ちます:const prev = usePrevious(value);

React.memoとuseMemoの違いは?

React.memoはコンポーネント全体をメモ化するHOCです:propsが変わらなければ再レンダリングを防ぎます。useMemoはコンポーネント内の特定の値をメモ化するフックです:依存配列によってレンダリング間で関数の結果をキャッシュします。

関数コンポーネントでgetDerivedStateFromPropsをシミュレートするには?

最も簡単な方法は、propsからの初期化を行うuseStateと、同期のためのpropsへの依存関係を持つuseEffectを使用することです。稀なケースでは、Reactは入力データが変更されたときにコンポーネントを強制的に再作成するためにkeyを使用することを推奨しています。

まとめ

  • Functional Component — 現代のReact標準:propsを受け取りJSXを返す関数。
  • フック(useState、useEffect)は関数コンポーネントにクラスなしで状態、効果、コンテキストを提供します。
  • 合成によるchildrenとカスタムフックは継承とHOCパターンを置き換えます。
  • React.memoとuseMemoは関数コンポーネントのパフォーマンス最適化を提供します。
  • TypeScriptと関数コンポーネントは厳密なpropsの型付けと自動型推論を提供します。
  • useEffectはクラスコンポーネントのすべてのライフサイクルメソッドを1箇所で置き換えます。
  • カスタムフックはHOCなしでコンポーネント間のロジックの抽出と再利用を可能にします。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください