はじめに
react-dropzone
でドロップされたファイルを React Hook Form
を使って他のinput要素と同じように一元管理する実装の 備忘録 です。
手順
1.useForm から setValue を取り出す。
2.onDrop の中で setValue に値を渡して、RHF で値を管理する。
実装例
・実装例では、useFormではなく、useFormContext を使っていますが、useFormでも正常に動作します。
export function ImageDragAndDropZone() {
const [previewImage, setPreviewImage] = useState<string>();
const { setValue } = useFormContext();
const onDrop = (files: File[]) => {
if (files.length !== 1) {
toast.error("画像は一つしかアップロード出来ません。", {
theme: "colored",
autoClose: 2000,
});
return;
}
const droppedImage = files[0];
// アップロードされた画像をstateで保持する
const reader = new FileReader();
reader.readAsDataURL(droppedImage);
reader.onload = () => {
setPreviewImage(reader.result as string);
};
// RHF側で一元管理する
setValue("image", droppedImage);
};
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
return (
<>
<ToastContainer />
<div
{...getRootProps()}
className={
isDragActive
? "border-2 border-dotted rounded-lg border-red-400 h-3/6"
: "border-2 border-dotted rounded-lg border-gray-300 h-3/6"
}
>
{previewImage && (
<Image
src={previewImage!}
alt="プレビュー画像"
width={9999}
height={9999}
className="h-full object-contain"
/>
)}
<input {...getInputProps()} />
{!previewImage && (
<p
className={
isDragActive
? "text-gray-600 flex justify-center items-center h-full text-center"
: "text-gray-400 flex justify-center items-center h-full text-center"
}
>
ここにアップロードしたい画像をドラッグ&ドロップしてください。
</p>
)}
</div>
</>
);
}
さいごに
学習させていただいた記事のリンクです。