こんにちは、広野です。
React 用ファイル選択 UI というと react-dropzone が有名なのですが、多機能すぎてわかりにくいです。機能はシンプルでいいから Material UI なデザインですぐに導入したかったので、MUI file input というモジュールを使ってファイル選択 UI をつくってみました。
つくった画面
モジュールを読み込んで配置しただけですが。
- 画面をクリックするとファイル選択ダイアログが表示されます。
- ドラッグ & ドロップでのファイル読込も可能です。
- ファイルの MIME タイプを読み込んで、エラーメッセージを出すようにしています。
- ファイルサイズもチェックできると思いますが、そこまではまだ作り込んでいません。
React コード
モジュールインストール
モジュールをインストールしておきます。(npm の例)
以下のサンプルコードをまんま使う場合は MUI もインストールが必要になります。
npm install --save mui-file-input
コード
import React, { useState } from 'react'; import { MuiFileInput } from 'mui-file-input'; import Typography from '@mui/material/Typography'; //中略 const [file, setFile] = useState(); const handleChangeFile = (newFile) => { setFile(newFile); }; //中略 <Typography variant="body1" component="h6" mt={1} gutterBottom>ファイル選択</Typography> <MuiFileInput value={file} onChange={handleChangeFile} variant="outlined" /> <br /> <Typography variant="caption" component="div" gutterBottom>MP3/MP4/WAV ファイルのみ、ファイルサイズは5MB以内。</Typography> {(file) && !(file.type === "audio/mpeg" || file.type === "video/mp4" || file.type === "audio/wav") && ( <Typography variant="caption" component="div" color="error.main" gutterBottom>このファイルタイプはサポートしていません。</Typography> )}
私の場合はこれで選択したファイルを Amazon S3 (Amplify Storage) にアップロードしています。
上記リンク先のブログで Amazon S3 環境が構築されている前提ですが、MUI file input でファイルを選択した後、file ステートに格納された BLOB を Amplify Storage にアップロードします。紹介されているコードは一部を以下のように変更します。アップロードするデータの contentType を application/json から変更する必要があります。
import { Storage } from 'aws-amplify'; //中略 const [progress, setProgress] = useState(0); //中略 //ファイルアップロード const putFile = async () => { await Storage.put( file.name, file, { level: "private", contentType: file.type, progressCallback(progress) { setProgress(progress.loaded/progress.total); } } ); };
まとめ
いかがでしたでしょうか?
HTML のデフォルトでファイル選択 UI をつくると超絶ダサイので、CSS なしですぐに導入できるデザイン済みモジュールを探していて MUI file input にたどり着きました。
本記事が皆様のお役に立てれば幸いです。