個人的な備忘録です。
画像のアップロードについては筆者の以下記事をご参照下さい。
環境
- react: 18.2.0
- next: 12.2.3
- react-dropzone: 14.2.2
- @chakra-ui/react: 2.2.4
やりたいこと
- react-dropzoneを使って、受付可能なファイルタイプを限定する
- Finder || Explorer での選択時は、指定ファイル以外選択できない
- 指定ファイル以外をドラッグ&ドロップした時はエラーメッセージを表示させる
完成イメージ
サンプルコード
- useDropzone へ accept オブジェクトを記述する
import { Img } from '@chakra-ui/react';
import { useState } from 'react';
import { useDropzone } from 'react-dropzone';
import styles from './contents.module.scss';
export const Contents = () => {
// ブラウザ表示用の paths
const [previewImagePaths, setPreviewImagePaths] = useState<string[]>();
// 選択された画像を処理
const onDrop = (acceptedFiles: File[]) => {
// 指定外のファイルがあれば、何も処理をしない
if (isDragReject) {
return;
}
const dataUrls = acceptedFiles.map((file) => URL.createObjectURL(file));
setPreviewImagePaths(dataUrls);
};
// 弾かれたファイル情報が、fileRejectionsに代入される
// ドラッグ&ドロップ時に Reject ファイルがあれば、isDragReject が true になる
const { fileRejections, isDragReject, getRootProps, getInputProps } = useDropzone({
onDrop,
// accept属性値の指定
accept: {
'image/jpeg': [],
},
});
const fileRejectionItems = fileRejections.map(({ file, errors }) => (
<>
<div>
{errors.map((e) => (
<p key={e.code}>
{file.name}は許可された拡張子ではありません
</p>
))}
</div>
</>
));
return (
<>
<div className={styles.contents}>
<div {...getRootProps({ className: 'dropzone' })}>
<input {...getInputProps()} />
<p>
Drag and drop some image files here, or click to select image files
</p>
</div>
</div>
{previewImagePaths &&
previewImagePaths.map((image, i) => (
<div key={i}>
<Img src={image} />
</div>
))}
{fileRejectionItems}
</>
);
};
参考文献