flow-flow-flow

[React] React x TypeScript でアップロードした画像ファイルをサムネイルとして表示する

f:id:thegriftsense:20210811003433j:plain 今やっている案件で、ユーザのアイコンの画像ファイルをアップロードして、その画像をサムネイルとして表示させて、OKボタン押下でサーバにアップロードするという処理があった。実装自体はシンプルだったけれど、はじめてやったのでメモしておく。

処理手順

  1. 1.inputタグ作成
  2. 2.inputタグのonChangeのハンドラ実装
  3. 3.ハンドラでのフローは、画像ファイルの取得、画像ファイルのbase64変換、state更新
  4. 4.imgタグ作成
  5. 5.stateをimgタグのsrcに設定

初めてだったのは、アップロードしたファイルをbase64に変換する処理くらい。 またひとつ賢くなってしまった。

コード全体

import React, { useCallback, useState } from "react";

export default function App() {
  // アップロードした画像ファイルから取得したbase64
  const [displayImage, setDisplayImage] = useState<string | ArrayBuffer | null>(null);
  /**
   * ファイルアップロードインプット変更時ハンドラ
   */
  const handlerChangeImageFileInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target?.files?.[0];
    if (!file) {
      return;
    }
    // 選択されたファイルが画像ファイル以外だったらreturn
    if (file.type !== 'image/jpeg' && file.type !== 'image/png') {
      // バリデーションメッセージ表示
      console.log('jpeg/pngファイルを選択してください');
      return;
    }
    const reader = new FileReader();
    // base64に変換
    reader.readAsDataURL(file);
    reader.onload = () => {
      // base64に変換した結果をstateにセットする
      setDisplayImage(reader.result);
    };
  }, []);
  return (
    <div>
      <h1>
        React x TypeScript
        でアップロードした画像ファイルをサムネイルとして表示する
      </h1>
      <input type="file" onChange={handlerChangeImageFileInput} />
      <img
        src={(displayImage as string) || ""}
        alt=""
        width="100px"
        height="100px"
      />
    </div>
  );
}

codeSandBoxで書いたサンプルコードと動くやつ

codesandbox.io

おわり。