ChatGPTを使用したアプリ開発記【プロフィール編集画面の実装】

## プロフィール編集画面を作成
```EditProfile.js
// React の useState（状態管理）と useEffect（副作用処理）をインポート。
import React, { useState, useEffect } from 'react';
// Firestore インスタンス db を自作ファイル FireBase.js からインポート。
import { db } from './FireBase';
// 	•	Firestore の操作に必要な関数をインポート。
//	•	doc: ドキュメント参照を作る。
//	•	getDoc: ドキュメントを取得。
//	•	setDoc: ドキュメントを書き込み・更新。
import { doc, getDoc, setDoc } from 'firebase/firestore';
// ページ遷移用の navigate 関数を取得するための React Router のフック。
import { useNavigate } from 'react-router-dom';

function EditProfile() {
// const userId = localStorage.getItem('currentUserId');
  const userId = localStorage.getItem('currentUserId');
//  name（名前）, bio（自己紹介）, status（メッセージ）の状態を定義。
  const [name, setName] = useState('');  
  const [bio, setBio] = useState('');
  const [status, setStatus] = useState('');
// 画面遷移に使う navigate 関数を取得。  
  const navigate = useNavigate();

// 	コンポーネントがマウントされたとき（または userId が変わったとき）に実行。
  useEffect(() => {
// 非同期関数 fetchProfile を定義（Firestore からプロフィールを取得）。  
    const fetchProfile = async () => {
    
      if (!userId) return;
      
// 'users' コレクションの userId ドキュメントを参照するオブジェクトを作成。   
      try {
        const docRef = doc(db, 'users', userId);
 // 上記ドキュメントを取得。       
        const docSnap = await getDoc(docRef);
 // データが存在するか確認。       
        if (docSnap.exists()) {
        // ドキュメントからデータを取り出す。
          const data = docSnap.data();
          // データが存在すれば、名前と自己紹介を state に設定。
          setName(data.name || '');
          setBio(data.bio || '');
        }
        // Firestore 操作でエラーが発生した場合のエラーハンドリング。
      } catch (err) {
      // エラーをコンソールに出力し、ステータスメッセージも更新。
        console.error('プロフィール取得エラー:', err);
        setStatus('❌ プロフィールの取得に失敗しました。');
      }
    };
    // fetchProfile を実行。userId が変わるたびに再実行される。
    fetchProfile();
  }, [userId]);
// フォーム送信時の処理関数を定義。
  const handleSubmit = async (e) => {
  // フォームのデフォルト動作（ページリロード）を防止。
    e.preventDefault();
    if (!userId) {
      setStatus('❌ ユーザーIDが無効です。');
      return;
    }
    // Firestore に name と bio を保存。merge: true で既存データと統合（上書きでなく追加/更新）。
    try {
      await setDoc(doc(db, 'users', userId), { name, bio }, { merge: true });
    // 成功したことをユーザーに通知。
      setStatus('✅ プロフィールを更新しました！');
    } catch (err) {
    // Firestore 書き込みでエラーが出たときにログを出力し、ユーザーに失敗を通知。
      console.error('更新エラー:', err);
      setStatus('❌ 更新に失敗しました。');
    }
  };

  if (!userId) {
    return <p className="text-red-500">ユーザーがログインしていません。</p>;
  }

  return (
    <div className="max-w-md mx-auto p-4">
      <h2 className="text-xl font-bold mb-4">プロフィール編集</h2>
      <form onSubmit={handleSubmit} className="space-y-4">
        <input
          type="text"
          placeholder="名前"
          value={name}
          onChange={(e) => setName(e.target.value)}
          className="w-full border px-3 py-2 rounded"
        />
        <textarea
          placeholder="自己紹介"
          value={bio}
          onChange={(e) => setBio(e.target.value)}
          className="w-full border px-3 py-2 rounded"
        />
        <button
          type="submit"
          className="w-full bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
        >
          保存
        </button>
        <button
          onClick={() => navigate(`/profile/${userId}`)}
          className="w-full bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
        >
          プロフィールに戻る
        </button>
        {status && <p className="text-sm mt-2 ml-4">{status}</p>}
      </form>
    </div>
  );
}

export default EditProfile;
```
- UI
![スクリーンショット 2025-05-13 7.16.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058366/7259ee41-54fa-4d62-8ccd-d6840c936ce5.png)
- Firestore
![スクリーンショット 2025-05-13 7.17.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058366/d059e0f5-4292-4a63-af31-14f539973aa9.png)

## プロフィール編集画面に遷移するボタン
```Profile.js
        {isCurrentUser && (
          <button
            onClick={() => navigate('/edit-profile')}
            className="bg-green-500 text-white px-4 py-2 rounded-2xl hover:bg-green-600 transition duration-200 shadow-md mb-4"
          >
            ✏️ プロフィールを編集
          </button>
        )}
```

![スクリーンショット 2025-05-13 7.19.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058366/adfa1d75-845a-4d84-927e-ffbb17d6cb1e.png)