【単純ミス】Next.jsアプリで画面間を行き来すると画像パスが抜けるバグの解決方法

# 掲題のバグは単なるコードの配置ミスだった
2024年12月25日に投稿した下記の記事について単純なコードミスがあったことに気が付いたので備忘録として記録しておきます。

https://qiita.com/SKY-HaYaTo/items/8fb9930bcdcd459dbbc4

上記↑の記事は、どんな記事だったというと「画面間でデータを`戻るボタン`で行き来した時になぜかCardコンポーネントの画像パスが空文字になる」という事象です。

画像以外の①イベントタイトルや②イベント内容とかはデータが抜け落ちないのに...データベースも確認してみるとやっぱり画像パスを文字列で格納するカラム「eventthumbnailpath」の中身が空文字になっていることが判明しました。

なので、上記↑の記事ではわざわざサーバ通信とデータ再登録をやむなく実装したという記事でした。

# 変なコードにずっと違和感があった
そもそもページ遷移するだけなのにデータベース登録する必要あるか？って記事書いてからもモヤモヤしてました。

まぁ、コードがおかしいのでしょうけどその原因を突き止めました。

# Formタグに`戻るボタン`を配置してたのがNG

つまり、こういうことです↓

![修正前後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/642a2108-1aa4-fbd7-1c98-5468c57fe78a.png)

そうなんです。
うっかりしてました。`Formタグ`に配置するのはサーバ通信するためのボタンである`編集するボタン`だけでした。

そのほかの、`クリアするボタン`や`戻るボタン`は`Formタグ`には普通は配置しません。
これをしてました...💦

なので、反省を生かして下記のようにコードを直しました↓

```app/auth/eventEdit/page.tsx
'use client'

import { useRouter, useSearchParams } from "next/navigation"
import { useCallback, useEffect,useState } from "react";
import SelectEvent from "@/app/pages/api/selectEvent";
import editTargetEvent from "@/app/pages/api/editEvent";
import eventThumbnailPathSave from "@/app/pages/api/saveEventthumbnailpath";
//import { GETQueryParams } from "@/app/pages/api/urlQueryParameters";

export default function EventEdit(){
    //ルーティングの設定
    const router = useRouter();
    const [loading,setLoading] = useState(false);
    const [error,setError] = useState<string | null>(null);

    //クライアントコンポーネントフックであるuseSearchParamsを使用する
    const searchParams = useSearchParams();
    //const [targetUserId,settargetUserId] = useState(0);

    //URL Query Paramsからパラメータを取得する
    const userId = searchParams.get('userId');
    const eventId = searchParams.get('eventId');

    console.log("GETパラメータから受け取ったユーザーIDは、" + userId);
    console.log("GETパラメータから受け取ったイベントIDは、" + eventId);
    
    //ダッシュボードに戻るボタン押下時の処理
    const backToMyDashboard = ()=>{
        router.push("/auth/login/dashboard");      
    }
    
    //状態でイベント情報を管理する
    const [targetEvent,settargetEvent] = useState<any[]>([]);//useState<any>(null);
    //画像のデフォルトURL
    const defaultImage = "/uploads/default.png";
    const [imageSrc,setImageSrc] = useState(defaultImage); 

    //let event:any;
    useEffect(()=>{
        const fetchEvent = async ()=>{
            try{
                console.log("内部のユーザーIDは、" +userId);
                const event = await SelectEvent(Number(userId),Number(eventId));
                console.log("サーバから取得してきた編集対象イベントは、" + event[0]);
                console.log("サーバから取得してきた編集対象イベントは、" + event[0].userid);
                settargetEvent(event[0]);

                console.log("useeffectの編集対象のイベントは、" + JSON.stringify(event[0]));                                                                                                                            
                if(event[0].eventthumbnailpath){
                    setImageSrc(event[0].eventthumbnailpath);
                }else{
                    setImageSrc(defaultImage);
                }
            }catch(error){
                console.error("イベントの取得中にエラーが発生しました：", error);
            }
        };
        fetchEvent();                
    },[userId,eventId]);//[userId,eventId]                     
    
    console.log("useEffect外の編集対象のユーザIDは、" + targetEvent.userid);
    console.log("useEffect外の編集対象のイベントタイトルは、" + targetEvent.eventtitle);            

    console.log("useEffect外の編集対象のイベントタイトル(targetEventtitle)は、" + targetEvent.eventtitle);

    //編集データを更新(登録)する
    const handleSubmit = useCallback(async (e:React.FormEvent<HTMLFormElement>)=>{
        console.log("更新ボタンを押下しました");
        e.preventDefault();
        const formData = new FormData(e.target as HTMLFormElement);
        console.log("編集後のイベント内容は、" + formData);
        const success = await editTargetEvent(formData);
        if(success){
            router.push("/auth/login/dashboard");
        }else{
            setError("イベントの更新に失敗しました。");
        }
        setLoading(false);
    },[router]);

    return (
        <div className="w-full w-96 content-center">
            <div>
                編集画面
            </div>
            <form onSubmit={handleSubmit} className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4" encType="multipart/form-data">
                <div className="userIdArea">
                    <input type="hidden" name="userId" value={targetEvent.userid || ''}/>                   
                </div>
                <div className="eventIdArea">
                    <input type="hidden" name="eventId" value={targetEvent.eventid || ''}/>
                </div>
                <div className="eventTitleArea">
                    <input
                        type="text"
                        name="eventTitle" 
                        defaultValue={targetEvent.eventtitle}
                        className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight"                                           
                    />
                    
                </div>
                <div className="eventDetailArea">
                    <textarea
                        name="eventDetail"
                        defaultValue={targetEvent.eventdetail}
                        className="block p-2.5 w-full text-sm text^gray-900 border border-gray-300"
                    ></textarea>
                </div>
                <div className="eventThumbnailArea">                     
                    <img src={imageSrc} alt="Event Thumbnail" className="w-full h-auto" />
                    <input type="file" name="eventThumbnailPath" className="file-input file-input-bordered file-input-primary w-full" />
                    <input type="hidden" name="eventThumbnailPath" defaultValue={targetEvent.eventthumbnailpath} />
                </div>
                <div className="eventEditArea">
                    <button type="submit" className="btn btn-primary" disabled={loading}>
                        {loading ? "更新中...":"更新する"}
                    </button>
                    {/*<button className="btn btn-accent">クリアする</button>*/}
                    {/*<button className="btn btn-secondary" onClick={backToMyDashboard}>戻る</button>*/}
                </div>
            </form>
            <div className="clearAndBackBtnArea">
                <button className="btn btn-accent">クリアする</button>
                <button className="btn btn-secondary" onClick={backToMyDashboard}>戻る</button>
            </div>            
        </div>
    )
}
```

これで、`戻るボタン`を押下して前画面に戻っても画像パスの文字列が空文字になることは無くなりました。

以上です。