Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

画像読み込みボタンの実装 #5

Open
3 of 5 tasks
kagomen opened this issue Nov 26, 2024 · 1 comment
Open
3 of 5 tasks

画像読み込みボタンの実装 #5

kagomen opened this issue Nov 26, 2024 · 1 comment

Comments

@kagomen
Copy link
Owner

kagomen commented Nov 26, 2024

  • ボタンから画像を読み込んだら、ボタンの下に読み込んだ画像を表示させる
  • 画像にマウスホバーしたら、一段暗くなるスタイルを当てる
  • タブ選択可能に
  • エンターキーでクリック可能に
  • メモリ管理

参考

@kagomen
Copy link
Owner Author

kagomen commented Nov 26, 2024

はい、このケースではメモリリークを防ぐために、URL.createObjectURL()で作成したオブジェクトURLを適切に解放する処理を追加することをお勧めします。

以下のように修正することができます:

"use client";

import { useState, useEffect } from "react";
import { Button } from "./ui/button";
import Image from "next/image";

export default function ImageUploadButton() {
  const [image, setImage] = useState<File>();
  const [previewUrl, setPreviewUrl] = useState<string>();

  // imageが変更されたときにプレビューURLを更新
  useEffect(() => {
    if (image) {
      const objectUrl = URL.createObjectURL(image);
      setPreviewUrl(objectUrl);

      // クリーンアップ関数でオブジェクトURLを解放
      return () => {
        URL.revokeObjectURL(objectUrl);
      };
    }
  }, [image]);

  function showImage(e: { target: HTMLInputElement }) {
    if (e.target.files && e.target.files[0]) {
      setImage(e.target.files[0]);
    }
  }

  return (
    <>
      <Button
        variant="outline"
        className="p-0 w-[140px] h-[calc(140px*1.4)]"
        asChild
      >
        <label role="button" tabIndex={0} className="cursor-pointer">
          <input type="file" accept="image/*" hidden onChange={showImage} />
          {previewUrl ? (
            <Image
              src={previewUrl}
              alt=""
              width="140"
              height={140 * 1.4}
              className="hover:opacity-70"
            />
          ) : (
            "+ upload"
          )}
        </label>
      </Button>
    </>
  );
}

主な変更点:

  1. previewUrl という新しいstate変数を追加して、オブジェクトURLを管理します。

  2. useEffect フックを使用して:

    • imageが変更されたときに新しいオブジェクトURLを作成
    • クリーンアップ関数で古いオブジェクトURLを解放

これらの変更により:

  • コンポーネントがアンマウントされたとき
  • 新しい画像がアップロードされたとき
  • imageのstateが変更されたとき

に適切にメモリが解放されます。

このメモリ管理は特に以下の場合に重要です:

  • ユーザーが多くの画像をプレビューする可能性がある場合
  • アプリケーションが長時間実行される場合
  • メモリ使用量を最適化する必要がある場合

この実装により、メモリリークを防ぎ、アプリケーションのパフォーマンスを維持することができます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant