I am building an image upload form using Next.js/React.js, and I want the user to be able to assign a tag to each upload. I also want to show the image preview using 'URL.createObjectURL'. The uploading works fine, but on the upload page where I try to iterate through the list of images to show the preview and show an input box to assign the tag, none of this is showing. I cannot work out why.
The code:
import { useState } from "react";
import Head from 'next/head'
import Layout, { siteTitle } from '../../components/layout'
import Image from 'next/image'
export default function PrivatePage(props) {
const [images, setImages] = useState([])
const [imageURLS, setImageURLS] = useState([])
const [tag, setTag] = useState(null)
const uploadImageToClient = (event) => {
var imageList = images
var urlList = imageURLS
if (event.target.files && event.target.files[0]) {
imageList.push(event.target.files[0]);
urlList.push(URL.createObjectURL(event.target.files[0]))
setImages(imageList);
setImageURLS(urlList);
}
};
const uploadTagToClient = (event) => {
if (event.target.value) {
const i = event.target.value;
setTag(i);
}
};
const uploadToServer = async (event) => {
const body = new FormData()
images.map((file, index) => {
body.append(`file${index}`, file);
});
body.append("tag", tag)
const response = await fetch("/api/file", {
method: "POST",
body
});
};
return (
<Layout home>
<Head>
<title>{siteTitle}</title>
</Head>
<div className="container">
<div className="row">
<h4>Select Images</h4>
<div className="col">
<input type="file" className="btn btn-outline-success-inverse" onChange={uploadImageToClient} />
<input type="file" className="btn btn-outline-success-inverse" onChange={uploadImageToClient} />
</div>
<div className="col">
</div>
<button
className="btn btn-outline-success-inverse"
type="submit"
onClick={uploadToServer}
>
Send to server
</button>
{images.map((file, index) => {
return (
<div class="row ">
<lead>{file.name}</lead>
<input type="text" onChange={uploadTagToClient} />
<image src={imageURLS[index]}/>
</div>)
})}
</div>
</div>
</Layout>
);
}
To clarify, nothing inside images.map is showing when I select images.