In this tutorial, we’ll see image file upload in React Material UI 5 with the help of react-hook-form. Ensure you have React MUI 5 and react-hook-form installed and configured before getting started.
React MUI 5 Image Upload With React Hook Form
1. Create Image File Upload with Icon in React MUI 5 using useForm and Controller from react-hook-form.
import { useForm, Controller } from 'react-hook-form';
import { Button, TextField } from '@mui/material';
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
const ImageUpload = () => {
const { control, handleSubmit } = useForm();
const onSubmit = data => {
// Handle the form data
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="image"
control={control}
defaultValue=""
render={({ field }) => (
<TextField
{...field}
type="file"
InputLabelProps={{ shrink: true }}
variant="outlined"
fullWidth
margin="normal"
/>
)}
/>
<Button
variant="contained"
color="primary"
startIcon={<CloudUploadIcon />}
type="submit"
>
Upload
</Button>
</form>
);
};
export default ImageUpload;
2. React MUI 5 Image File Upload Form Validation using react-hook-form and TypeScript.
import React from 'react';
import { useForm, Controller, SubmitHandler } from 'react-hook-form';
import { Button, TextField } from '@mui/material';
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
// Define a type for the form data
type FormData = {
image: FileList;
};
const ImageUpload: React.FC = () => {
const { control, handleSubmit, formState: { errors } } = useForm<FormData>();
const onSubmit: SubmitHandler<FormData> = data => {
// Handle the form data
console.log(data);
};
// Validation rule for image files
const imageValidation = {
required: 'An image file is required',
validate: (fileList: FileList) => {
if (fileList.length === 0) {
return 'An image file is required';
}
const file = fileList[0];
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml'];
if (!allowedTypes.includes(file.type)) {
return 'Invalid file type. Please select an image (jpeg, png, gif, svg).';
}
return true;
}
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="image"
control={control}
rules={imageValidation}
defaultValue=""
render={({ field }) => (
<TextField
{...field}
type="file"
InputLabelProps={{ shrink: true }}
variant="outlined"
fullWidth
margin="normal"
error={!!errors.image}
helperText={errors.image ? errors.image.message : ''}
/>
)}
/>
<Button
variant="contained"
color="primary"
startIcon={<CloudUploadIcon />}
type="submit"
>
Upload
</Button>
</form>
);
};
export default ImageUpload;
3. React MUI 5 Image File Upload with Preview using react-hook-form and TypeScript.
import React, { useState } from "react";
import { useForm, Controller, SubmitHandler } from "react-hook-form";
import { Button, TextField, Box, Card, CardMedia, Container } from "@mui/material";
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
// Define a type for the form data
type FormData = {
image: FileList;
};
const ImageUpload: React.FC = () => {
const {
control,
handleSubmit,
formState: { errors },
} = useForm<FormData>();
const [imagePreview, setImagePreview] = useState<string | null>(null);
const onSubmit: SubmitHandler<FormData> = (data) => {
// Handle the form data
console.log(data);
};
// Function to handle image preview
const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files[0]) {
const file = e.target.files[0];
setImagePreview(URL.createObjectURL(file));
}
};
// Validation rule for image files
const imageValidation = {
required: "An image file is required",
validate: (fileList: FileList) => {
if (fileList.length === 0) {
return "An image file is required";
}
const file = fileList[0];
const allowedTypes = [
"image/jpeg",
"image/png",
"image/gif",
"image/svg+xml",
];
if (!allowedTypes.includes(file.type)) {
return "Invalid file type. Please select an image (jpeg, png, gif, svg).";
}
return true;
},
};
return (
<Container maxWidth="sm">
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="image"
control={control}
rules={imageValidation}
defaultValue=""
render={({ field }) => (
<TextField
{...field}
type="file"
onChange={(e) => {
field.onChange(e);
handleImageChange(e);
}}
InputLabelProps={{ shrink: true }}
variant="outlined"
fullWidth
margin="normal"
error={!!errors.image}
helperText={errors.image ? errors.image.message : ""}
/>
)}
/>
{imagePreview && (
<Box sx={{ my: 2, display: "flex", justifyContent: "center" }}>
<Card sx={{ maxWidth: 345 }}>
<CardMedia component="img" image={imagePreview} alt="Preview" />
</Card>
</Box>
)}
<Button
variant="contained"
color="primary"
startIcon={<CloudUploadIcon />}
type="submit"
sx={{ mt: 2 }}
>
Upload
</Button>
</form>
</Container>
);
};
export default ImageUpload;