Goal: Trying to upload a video to the server and display the video preview before the upload.
Bug:The video preview is working fine for the first time but when I try to upload the video again the new video preview does not display and but the old video keeps on playing.
My Code: I have a state videoPreview and I am using it as a source to my video tag source. The setVideoPreview is set to the uploaded file. This only works the first time but if I upload the video again it does not get rerendered again and the preview of the previous video keeps on playing. Here is my code snippet
<label for="videos">
<video
width="400"
height="150"
style={{ height: "143px", objectFit: "contain" }}
autoPlay
loop
>
<source src={videoPreview} />
</video>
</label>
<input
type="file"
id="videos"
accept="video/*"
className="text-transparent -ml-52"
onChange={(e) => {
const files = e.target.files;
let myFiles = Array.from(files);
const fileReader = new FileReader();
fileReader.onload = () => {
if (fileReader.readyState === 2) {
formik.setFieldValue("video", myFiles);
setVideoPreview(fileReader.result);//this is my state
}
};
if (e.target.files[0]) {
fileReader.readAsDataURL(e.target.files[0]);
}
}}
value={formik.values.video.name}
/>
I have no idea why the state is not updating or if it's updating the preview is not changing.
After some research, I was able to solve the bug via the onloadstart and onloadend event listeners of the FileReader object. I set the videoPreview to null on the onloadstart and to the FileReader.result on the onloadend.
Here is the code I used in the onChange function
onChange={(e) => {
const files = e.target.files;
let myFiles = Array.from(files);
const fileReader = new FileReader();
fileReader.onload = () => {
if (fileReader.readyState === 2) {
formik.setFieldValue("video", myFiles);
}
};
fileReader.onloadstart = () => {
setVideoPreview(null);
};
fileReader.onloadend = () => {
setVideoPreview(fileReader.result);
};
if (e.target.files[0]) {
fileReader.readAsDataURL(e.target.files[0]);
}
}}