見出し画像

【React実践】画像アップロードを劇的に使いやすく!URL.createObjectURL で作る「即時プレビュー」の実装テクニック


62日目はバリデーションの決定版「Zod」を学び、データの整合性を守る方法を習得しました。本日63日目は、よりリッチなユーザー体験を提供するための「ファイル選択と画像プレビュー機能」 を学習します。

SNSやプロフィール設定、ブログ投稿機能には欠かせない「ブラウザ上で画像を確認する」仕組みを、ReactのHooksを使ってスマートに実装しましょう!


はじめに:画像選択に「安心感」をプラスする

ユーザーが画像をアップロードする際、ファイル名だけが表示されるよりも、「今どの画像を選んだか」がパッと見えるプレビュー機能があるだけで、アプリの品質は一気にプロレベルに引き上がります。

サーバーに送信する前に、ブラウザのメモリを活用して画像を表示させる方法をマスターしましょう。


💡 1. プレビューの仕組み:URL.createObjectURL

ブラウザには、選択されたローカルファイルを一時的なURL(メモリ上のパス)に変換する機能があります。

💻 基本的な実装例

export const ImageUploader = () => {
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]; // 💡 最初の1枚を取得
    
    if (file) {
      // 💡 メモリ上に一時的なURLを作成
      const url = URL.createObjectURL(file);
      setPreviewUrl(url);

      // 注意:メモリリークを防ぐための後処理については後述!
    }
  };

  return (
    <div className="flex flex-col items-center gap-4">
      <input type="file" accept="image/*" onChange={handleFileChange} />
      
      {previewUrl && (
        <div className="mt-4">
          <p className="text-sm text-gray-500 mb-2">プレビュー:</p>
          <img src={previewUrl} alt="Preview" className="w-40 h-40 object-cover rounded-lg shadow" />
        </div>
      )}
    </div>
  );
};

💡 2. メモリリークを防ぐクリーンアップ

URL.createObjectURL で作ったURLは、ブラウザが閉じられるまでメモリを専有し続けます。画像が切り替わった時やコンポーネントが消える時に、古いURLを解放(revoke)するのがプロの作法です。

useEffect(() => {
  // コンポーネントが消えるときや、previewUrlが更新される前にメモリを解放
  return () => {
    if (previewUrl) URL.revokeObjectURL(previewUrl);
  };
}, [previewUrl]);

💡 3. 実務での応用:ドラッグ&ドロップ

さらに高度なUIとして、react-dropzone などのライブラリを使うと、枠の中にファイルを投げ込む直感的なアップローダーも簡単に作れるようになります。


📝 63日目のまとめと課題

✅ 本日の習得ポイント

  • URL.createObjectURL: サーバー通信なしで、ローカルファイルを画像として表示する。

  • メモリ管理: URL.revokeObjectURL でブラウザの負担を減らす。

  • ユーザー体験: プレビューがあることで、誤送信を防ぎ満足度を高める。

📝 63日目の課題

  1. 自分のアプリで「画像をアップロードする場所(例:プロフィール、記事投稿)」を具体的に決めてみましょう。

  2. 「画像以外のファイル(PDFなど)」が選択された時に、適切なアイコン(ファイルの絵など)を出すにはどう条件分岐すればいいか考えてみてください。

「複数の画像を同時にプレビューする方法が知りたい」や「ドラッグ&ドロップの実装を詳しく見てみたい」など、興味がある方向を教えてください!

もっとReactを学びたい人はここから!



#エンジニアと繋がりたい #プログラミング学習 #React #100DaysOfCode #今日の積み上げ #フロントエンド開発 #JavaScript

いいなと思ったら応援しよう!