初心者向け：Reactのフックとは何か、絶対に理解する

![サムネイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4079931/3e79a007-b8b7-4b11-88fe-73a5a4b1aabe.png)
## 目次

1. [Reactのコンポーネントとは？](#1-reactのコンポーネントとは)
2. [クラスコンポーネントの仕組みと特徴](#2-クラスコンポーネントの仕組みと特徴)
3. [関数コンポーネントの仕組みと特徴](#3-関数コンポーネントの仕組みと特徴)
4. [クラスコンポーネントと関数コンポーネントの比較](#4-クラスコンポーネントと関数コンポーネントの比較)
5. [Reactフック（Hooks）とは？](#5-reactフックhooksとは)
6. [主要フックの詳細解説](#6-主要フックの詳細解説)
    - [useState](#usestate--状態管理の基本)
    - [useReducer](#usereducer--複雑な状態管理)
    - [useEffect](#useeffect--副作用の処理)
    - [useLayoutEffect](#uselayouteffect--レイアウト後の副作用)
    - [useRef](#useref--値やdom参照の保持)
    - [useImperativeHandle](#useimperativehandle--ref経由でメソッド公開)
    - [useMemo](#usememo--計算結果のメモ化)
    - [useCallback](#usecallback--関数のメモ化)
    - [useContext](#usecontext--グローバル値の共有)
    - [useDebugValue](#usedebugvalue--デバッグ用ラベル)
7. [カスタムフックの活用](#7-カスタムフックの活用)
8. [よくあるエラーと注意点](#8-よくあるエラーと注意点)
9. [まとめ・次のステップ](#9-まとめ次のステップ)

## 1. Reactのコンポーネントとは？

Reactのコンポーネントは、UIを構成する再利用可能な部品です。
「ボタン」「リスト」「ページ」など、画面の一部をひとつのコンポーネントとしてまとめます。

## 2. クラスコンポーネントの仕組みと特徴

**クラスコンポーネント**は、React初期から使われている伝統的なコンポーネント定義方法です。
JavaScriptの`class`構文を使い、`React.Component`を継承して作成します。

**主な特徴：**

- `render()`メソッドでUI（JSX）を返す
- `this.state`で内部状態を管理
- `setState()`で状態を更新
- `componentDidMount`や`componentDidUpdate`など、**ライフサイクルメソッド**を使える
- propsは`this.props`で参照

**例：**

```jsx
import React, { Component } from 'react';

class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
      </div>
    );
  }
}

export default MyComponent;
```

**メリット：**

- 複雑な状態やライフサイクル制御がしやすい
- オブジェクト指向に馴染みがある人には理解しやすい

**デメリット：**

- 構文が複雑で冗長になりやすい
- `this`の扱いが難しい
- コード量が多くなりがち
- フック（Hooks）は使えない

## 3. 関数コンポーネントの仕組みと特徴

**関数コンポーネント**は、よりシンプルな構文でコンポーネントを定義できる方法です。
JavaScriptの関数として定義し、propsを引数で受け取り、JSXを返します。

**主な特徴：**

- シンプルな関数として記述
- propsは引数で受け取る
- Hooks（フック）を使うことで、状態管理や副作用処理が可能

**例：**

```jsx
import React from 'react';

const MyComponent = () => {
  const [count, setCount] = React.useState(0);
  return (
    <div>
      <p>Count: {count}</p>
    </div>
  );
};

export default MyComponent;
```

**メリット：**

- 構文がシンプルで短い
- フックを使えばクラスコンポーネントと同じ機能が実現可能
- 再利用やテストがしやすい
- `this`の扱いで悩まない

**デメリット：**

- Hooks導入前は、状態やライフサイクル制御ができなかった

## 4. クラスコンポーネントと関数コンポーネントの比較

| 項目 | クラスコンポーネント | 関数コンポーネント |
| :-- | :-- | :-- |
| 定義方法 | class構文＋React.Component継承 | 関数（function/アロー関数） |
| 状態管理 | this.state / setState | useState, useReducer（Hooks） |
| ライフサイクル制御 | componentDidMount等の専用メソッド | useEffect, useLayoutEffect（Hooks） |
| コードの簡潔さ | 冗長になりやすい | シンプルで短い |
| Hooksの利用 | 不可 | 可能 |
| テスト・再利用性 | やや低い | 高い |
| 初心者の学習コスト | 高め（thisやライフサイクルの理解が必要） | 低め |

> 現在は**関数コンポーネント＋フック**が主流です。

## 5. Reactフック（Hooks）とは？

**Reactフック（Hooks）**は、関数コンポーネントで「状態管理」や「副作用処理」などを実現するための特別な関数群です。
これにより、クラスコンポーネントでしかできなかった高度な機能も、シンプルな関数コンポーネントで実装できるようになりました。

## 6. 主要フックの詳細解説

### useState ― 状態管理の基本

- **用途**：コンポーネント内で値（状態）を保持・更新したいとき
- **特徴**：初期値を渡して呼び出し、[現在値, 更新関数]の配列を返す

```jsx
const [count, setCount] = useState(0);
setCount(count + 1); // 状態を更新
```

- 状態は直接変更せず、必ず更新関数を使う

---

### useReducer ― 複雑な状態管理

- **用途**：複数の値をまとめて管理したい、状態遷移が複雑な場合
- **特徴**：reducer関数とdispatchで状態を操作

```jsx
const initialState = { count: 0 };
function reducer(state, action) {
  switch (action.type) {
    case 'increment': return { count: state.count + 1 };
    case 'decrement': return { count: state.count - 1 };
    default: throw new Error();
  }
}
const [state, dispatch] = useReducer(reducer, initialState);
```

- Reduxのような書き方ができる

---

### useEffect ― 副作用の処理

- **用途**：データ取得、イベント登録、タイマー設定などの副作用処理
- **特徴**：依存配列で実行タイミングを制御、クリーンアップも可能

```jsx
useEffect(() => {
  // 副作用処理
  return () => {
    // クリーンアップ
  };
}, [依存値]);
```

- 空配列ならマウント時のみ実行

---

### useLayoutEffect ― レイアウト後の副作用

- **用途**：DOMのレイアウトが確定した直後に実行したい場合
- **特徴**：useEffectよりも早いタイミングで実行される

```jsx
useLayoutEffect(() => {
  // レイアウト直後の処理
}, []);
```

- レイアウト計測やスクロール位置調整に便利

---

### useRef ― 値やDOM参照の保持

- **用途**：再レンダリング不要な値やDOM要素の参照を保持
- **特徴**：ref.currentで値を保持、変更しても再描画されない

```jsx
const inputRef = useRef(null);
<input ref={inputRef} />
```

- 前回値やタイマーIDの保持にも使える

---

### useImperativeHandle ― ref経由でメソッド公開

- **用途**：親コンポーネントから子コンポーネントのメソッドを呼び出したいとき
- **特徴**：forwardRefと組み合わせて使う

```jsx
const FancyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => inputRef.current.focus()
  }));
  return <input ref={inputRef} />;
});
```

- 内部実装を隠しつつ必要なメソッドだけ公開できる

---

### useMemo ― 計算結果のメモ化

- **用途**：計算コストの高い処理の結果をメモ化
- **特徴**：依存値が変わらない限り再計算しない

```jsx
const expensiveValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
```

- パフォーマンス最適化に有効

---

### useCallback ― 関数のメモ化

- **用途**：関数をメモ化して不要な再レンダリングを避ける
- **特徴**：依存値が変わらなければ同じ関数参照を維持

```jsx
const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);
```

- 子コンポーネントへのコールバック最適化に使う

---

### useContext ― グローバル値の共有

- **用途**：テーマや認証情報などグローバルな値を共有
- **特徴**：Contextオブジェクトを作成し、useContextで値を取得

```jsx
const ThemeContext = React.createContext("light");
const theme = useContext(ThemeContext);
```

- Providerで値を供給し、ツリー内のどこからでも参照可能

---

### useDebugValue ― デバッグ用ラベル

- **用途**：カスタムフックの値をReact DevToolsで見やすくする
- **特徴**：開発時のデバッグ支援

```jsx
useDebugValue(value ? "有効" : "無効");
```


---

## 7. カスタムフックの活用

複数のコンポーネントで使いたいロジックを「カスタムフック」としてまとめて再利用できます。
カスタムフックは`use`で始まる関数名にし、内部で他のフックを自由に組み合わせてOKです。

```jsx
function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  return width;
}
```

## 8. よくあるエラーと注意点

- **Invalid hook call**
→ フックは関数コンポーネントまたはカスタムフックのトップレベルでのみ使う
- **useEffectの依存配列ミス**
→ 無限ループや意図しない挙動の原因
- **useRefの値を直接変更しても再描画されない**
- **useContextの値が変わると、ツリー内のすべての利用箇所が再レンダリングされる**


## 9. まとめ・次のステップ

- Reactのコンポーネントは「クラス」と「関数」の2種類
- 現在は**関数コンポーネント＋フック**が主流
- フックを使えば、状態管理・副作用・パフォーマンス最適化・グローバル値共有など、あらゆる機能がシンプルに実装可能
- まずは`useState`と`useEffect`から慣れよう
- カスタムフックでロジックを再利用しよう


**フックを理解すれば、React開発が一気に楽しく・効率的になります！
ぜひこの記事を参考に、全フックとコンポーネントの違いをしっかり身につけてください。**

> ※本記事は2025年6月時点のReact最新情報と公式ドキュメント、各種解説記事を参考に執筆しています。