Getting "InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable" when trying to update state variable onChange
Good day I can't seem to figure this one out. I'm getting "InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable" let me explain:
I have a CustomUpload component:
export const CustomUpload = ({ name, children, accept, onChange, value }) => {
const fileUpload = useRef(null);
const handleClick = (e) => {
e.preventDefault();
fileUpload.current.click();
};
return (
<div className="custom-upload-container">
<label
style={{ textAlign: "center", fontFamily: "var(--montserrat-text)" }}
htmlFor={name}
>
{children}
</label>
<div className="custom-upload-input-container">
<p>{value.name}</p>
<div className="input-container">
<input
ref={fileUpload}
className="custom-upload"
type="file"
name={name}
accept={accept}
onChange={onChange}
value={value}
/>
</div>
<CustomButton onClick={handleClick}>Browse</CustomButton>
</div>
</div>
);
};
And then I have a page where a user has to submit 5 images, but for simplicity sake I will use two:
export const Images = () => {
const [data, setData] = useState({
image1: "",
image2: "",
});
const { image1, image2 } = data;
const handleOnChange = (value, fieldName) => {
setData({...data, [fieldName]: value });
return(
<form>
<CustomUpload
name="image1"
onChange={(e) => handleOnChange(e.target.files[0], "image1")}
value={image1}
accept="image/*"
>
First Image
</CustomUpload>
<CustomUpload
name="image2"
onChange={(e) => handleOnChange(e.target.files[0], "image2")}
value={image2}
accept="image/*"
>
Second Image
</CustomUpload>
</form>
}
The problem is that when I select the image it is giving me the error and I can't seem to figure out how I am supposed to solve it. Thank you.
Solution 1:
I figured it out. So the issue was that I was assigning the value of the CustomUpload using the value prop, which is normal for text input, but seems to break a file input.
<CustomUpload
name="image1"
onChange={(e) => handleOnChange(e.target.files[0], "image1")}
>>> value={image1} //remove this line.
accept="image/*"
>
First Image
</CustomUpload>
Should be:
<CustomUpload
name="image1"
onChange={(e) => handleOnChange(e.target.files[0], "image1")}
accept="image/*"
>
First Image
</CustomUpload>
Btw this is a really neat solution for handling multiple file uploads and having a single onChangeHandler and useState hook. Hope this helps people out :D