I am working on Nextjs and try to upload a single file. Every time I attach new file, then I get this error at the console log.
At the console, I see this error:
Warning: A component is changing an uncontrolled input of type file to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.
Then, the second one is:
react-dom.development.js:2592 Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.
Here is my sample code:
<div className="form-group">
<label htmlFor="p_file">Image</label>
<input
id="p_file"
type="file"
className="form-control-file"
value={formData.image}
onChange={ e => onChangeImage(e)} />
</div>
const [formData, setFormData] = useState({
...,
image: undefined
});
const onChangeImage = event => {
console.log(event.target.files[0]);
setFormData( prev => ({
...prev,
image: event.target.files[0]
}));
}
From the React documentation on uncontrolled elements:
In React, an
<input type="file" />
is always an uncontrolled component because its value can only be set by a user, and not programmatically.
This is a security feature, to ensure that you can not pull data from a users disk without them specifically choosing to do so.
To me, it seems like this isn't what you're trying to do. All you want to do is display the name of the selected file. You can do that by creating your own label and button, with a hidden file element. When you click your custom button, call the click event imperatively on the HTMLFileInput. Register your change event on the file input, and update your custom element with the response.
If you want to fire the onChange event each time you select a file (regardless of whether it is the same file or a different one) you could set value={''} in your input. This will empty the input every time it is rendered.
I drew inspiration for this answer from chrisv here:
React controlled component input value with empty string
See example below:
import * as React from "react";
import {useEffect, useState} from "react";
const FileComponentTest = () => {
const [file, setFile] = useState(null);
useEffect(() => {
console.log("File has been set.")
},[file]);
return (
<React.Fragment>
<input
type="file"
onChange= {(e) => setFile(e.target.files[0])}
value ={""}
/>
</React.Fragment>
)
};
I get no errors in the console with this.
Update:
Please see link to fiddle below:
https://jsfiddle.net/geoj12/tjbvpyzs/11/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With