こんにちは、広野です。
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 にたどり着きました。
本記事が皆様のお役に立てれば幸いです。