I am trying to make a component that uploads an image by opening a custom modal and after selecting the image file it displays the image.
But after selecting the image the screen goes blank. The custom modal opens on top of the current screen.
Here is my typescript code
import React, { useState, useRef } from "react";
const ImgUpldChild = () => {
const [image, setImage] = useState<string | null>(".jpg/640px-Outdoors-man-portrait_%28cropped%29.jpg");
const [isModalOpen, setIsModalOpen] = useState(false);
const openModal = () => setIsModalOpen(true);
const closeModal = () => setIsModalOpen(false);
const removeImage = () => {
setImage(null);
};
const fileInputRef = useRef<HTMLInputElement>(null);
// Open file picker when div is clicked
const handleDivClick = () => {
if (fileInputRef.current) {
fileInputRef.current.click();
}
};
// Handle image selection
const handleImageChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) {
console.warn("No file selected");
return;
}
const reader = new FileReader();
reader.onload = () => {
try {
console.log("FileReader triggered");
console.log("FileReader result type:", typeof reader.result);
console.log("FileReader result:", reader.result);
if (typeof reader.result === "string") {
setTimeout(() => setImage(reader.result as string), 1000);
}
} catch (error) {
console.error("Error in reader.onload:", error);
}
};
reader.readAsDataURL(file);
};
return (
<div>
<div className="row">
<div className="col-sm-4 mb-4">
<div className="form-group">
<label className="guardian-img-box col-11">
Father’s Photo
{image ? (
<div className="img-dlt-div">
<img src={image} alt="" className="preview-image" />
<button onClick={removeImage} className="delete-button">
<i className="far fa-trash-alt"></i>
</button>
</div>
) : (
<div className="upload-icon" onClick={openModal}>
<i className="fa-solid fa-arrow-up-from-bracket"></i>
</div>
)}
</label>
</div>
</div>
</div>
{/* Modal for uploading image */}
{isModalOpen && (
<div className="modal-overlay">
<div className="upload-modal">
<div className="upload-content">
<div className="drag-drop-box col-4">
<span className="plus-icon">+</span>
</div>
<p className="upload-img-txt">Drag and drop photo here</p>
<div className="divider">Or</div>
<div className="upload-button" onClick={handleDivClick}>
<i className="fa-solid fa-arrow-up-from-bracket"></i>
<input type="file" accept="image/png, image/jpeg" ref={fileInputRef} onChange={handleImageChange} style={{ display: "none" }} />
</div>
<p className="upload-img-txt">Upload file</p>
<p className="file-info">PNG, JPG up to 2MB</p>
</div>
<button className="close-button" onClick={closeModal}>
✖
</button>
</div>
</div>
)}
</div>
);
};
export default ImgUpldChild;
the reader.result shows the output in console:-
FileReader triggered ImgUpldChild.tsx:37
FileReader result type: string ImgUpldChild.tsx:38
FileReader result: data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/4gxUSUNDX1BST0ZJTEUAAQEAAAxEVUNDTQJAAABtbnRyUkdCIFhZWiAH0wAEAAQAAAAAAABhY3NwTVNGVAAAAABDQU5PWjAwOQA....
but after that i get:-
Uncaught NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node. at removeChild at ImgUpldChild.tsx:41:1
the line 41 of the code is setTimeout(() => setImage(reader.result as string), 100);
I have added an image link in the initial value of image in the useState() replace that with null or delete the current image with delete icon. Also, fontawesome fonts are used in this so either replace them with some symbol or use the fontawesome cdn.
Can someone explain what am I doing wrong or why react is crashing?
Edit 1:- The component is working fine in codesandbox but there is issue while running it in the project. So, these are the error messages in the console
(contd.)