【初心者向け】React NativeのuseEffectの解説。サンプルアプリ付き



# 1. 目的
- 最近ReactNativeで個人開発を始めたので、復習のため知識をまとめます
- この記事では、React NativeのuseEffectフックについて初心者向けにわかりやすく解説します
- useEffectの役割や使い方を理解し、実際に簡単なサンプルアプリを作成して動作を確認します

# 2. 対象読者
- React Nativeをこれから学びたい人
- 何かしらのプログラミング言語の基礎を学んだことがある人（JavaScriptの基礎があると理解しやすい）
- 環境：Mac OS  

# 3. React Nativeとは？

## 3-1. React Nativeの概要

React Native（リアクトネイティブ）は、Facebook（現在のMeta）が開発したオープンソースのフレームワークです。JavaScript（特にReact）を使ってiOSとAndroidアプリを同時に開発できるのが特徴です。

## 3-2. ReactとReact Nativeの違い

項目	React	React Native
開発対象	Webアプリ	モバイルアプリ（iOS/Android）
レンダリング	HTML + CSS	ネイティブコンポーネント（View, Textなど）
スタイリング	CSS	StyleSheet（JSオブジェクト）

# 4. useEffectとは？

## 4-1. useEffectの概要

useEffectは、コンポーネント(Reactで作る部品)のライフサイクル（マウント・更新・アンマウント）に合わせて処理を実行するためのReactフックです。

React Nativeでは、データの取得、イベントの登録、タイマーの設定などをuseEffectを使って記述します。

## 4-2. useEffectの基本構文
```React: 
import React, { useEffect } from 'react';
import { Text } from 'react-native';

const SampleComponent = () => {
  useEffect(() => {
    console.log("コンポーネントがマウントされました！");

    return () => {
      console.log("コンポーネントがアンマウントされました！");
    };
  }, []);

  return <Text>Hello, useEffect!</Text>;
};

export default SampleComponent;
```

## 4-3. useEffectの引数
- 第1引数：実行する関数（useEffectの中で行いたい処理を書く）
- 第2引数（依存配列）：useEffectを「いつ実行するか」を決めるリスト
    - []（空の配列）：コンポーネントが**画面に初めて表示されたとき（マウント時）** に1回だけ実行
    - [変数]：指定した変数の値が変わるたびに実行
    - 省略（何も指定しない）：コンポーネントが**描き直されるたび（再レンダリング）**に実行

# 5. サンプルアプリを作って動作確認

## 5-1. アプリの概要

useEffectを使って、コンポーネントのマウント時にデータを取得し、一定時間ごとにカウントアップするアプリを作成します。

## 5-2. Expo環境を準備

React Nativeで手軽に開発するために、Expoを使います。

```sh
npx create-expo-app useEffectSample
cd useEffectSample
```
![スクリーンショット 2025-03-02 11.52.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/7702330b-7e24-48c3-bbb8-cddbe8c8928e.png)

```sh
npm install
npm start
```
![スクリーンショット 2025-03-02 11.54.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/6daebfe8-278a-4203-a5b7-b27e6021d88d.png)


（npx create-expo-appがない場合は、npm install -g expo-cliでインストール）
ターミナルで「i」を押し、iOSのシュミレーターが起動されます
![スクリーンショット 2025-03-02 12.06.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/0b94c3b9-5a40-4497-a992-18305e85d3ea.png)

![スクリーンショット 2025-03-02 12.05.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/fdf5d9ca-63a0-410f-9fe8-c9a87b000fd4.png)




## 5-3. index.tsxのコード
app/index.tsxを以下のコードに書き換えてください。

```React: index.tsx
import React, { useState, useEffect } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';

const IndexScreen = () => {
  const [count, setCount] = useState(0);
  const [message, setMessage] = useState("データ取得中...");

  // 2秒ごとにメッセージを変更
  useEffect(() => {
    const messageInterval = setInterval(() => {
      setMessage((prevMessage) =>
        prevMessage === "Hello, useEffect!"
          ? "React Native勉強中"
          : "Hello, useEffect!"
      );
    }, 2000);

    return () => clearInterval(messageInterval); // クリーンアップ
  }, []);

  // 1秒ごとにカウントアップ
  useEffect(() => {
    const countInterval = setInterval(() => {
      setCount((prevCount) => prevCount + 1);
    }, 1000);

    return () => clearInterval(countInterval); // クリーンアップ
  }, []);

  return (
    <View style={styles.container}>
      <Text style={styles.text}>{message}</Text>
      <Text style={styles.counter}>カウント: {count}</Text>
      <Button title="リセット" onPress={() => setCount(0)} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  text: { fontSize: 20, marginBottom: 20 },
  counter: { fontSize: 30, marginBottom: 20 },
});

export default IndexScreen;
```

フォルダ構成は以下の画像のようになっています。
![スクリーンショット 2025-03-02 12.13.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/3cfc9b3b-5ca4-43c6-b525-6518e73f4ea0.png)



## 5-4. 動作確認

npm startまたはexpo startを実行し、エミュレーターまたは実機で確認します。

期待される動作
- 最初に「データ取得中…」と表示
- 2秒ごとに「Hello, useEffect!」「React Native勉強中」に変わる
- 1秒ごとにカウントが増える
- 「リセット」ボタンを押すとカウントが0に戻る

![スクリーンショット 2025-03-02 12.22.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/00c332c5-8fff-4610-b70f-82a91269b349.png)
![スクリーンショット 2025-03-02 12.22.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/37566049-c313-45ca-b77e-8fcdffb4cba8.png)


# 6. まとめ

✅ useEffectのポイント
- コンポーネントのライフサイクル（マウント・更新・アンマウント）に合わせた処理が書ける
- 依存配列（[]）の設定によって、実行タイミングをコントロールできる
- データ取得、イベント登録、タイマーの設定・解除などに利用できる

✅ 学んだこと
- useEffectの基本的な使い方
- 依存配列の役割
- サンプルアプリでの活用方法

# 8. 補足
## 8.1　用語整理
- 依存配列：useEffectが「いつ実行されるか」を決めるリスト。指定した変数の値が変わるとuseEffectが動く。
- コンポーネント：アプリの部品（ボタンや画面の一部など）。Reactではコンポーネントを組み合わせて画面を作る。
- 再レンダリング：コンポーネントが新しい情報で描き直されること（ボタンを押して文字が変わるなど）。
- ライフサイクルとは？
  - コンポーネントが 「生まれてから消えるまで」 の流れのこと。
  - アプリでは、画面に表示されたり（マウント）、データが変わったり（更新）、画面が閉じられたり（アンマウント）することがあります。

- ライフサイクルの3つの段階
	1.	マウント（Mount）：コンポーネントが画面に表示される（初回表示）
	2.	更新（Update）：データの変化でコンポーネントが描き直される（再レンダリング）
	3.	アンマウント（Unmount）：コンポーネントが画面から消える（削除される）

    
##  8.2 公式ドキュメント

より詳しく知りたい方は、公式ドキュメントを参考にしてください。

🔗 React Native公式サイト
https://reactnative.dev/

🔗 React公式サイト（Hooks）
https://react.dev/reference/react/useEffect

## 8.3 サンプルコード(Git)
ご参考までに（予告なく消される可能性ありです）
https://github.com/katoyuki1/useEffectSample