i want to add data after uploading 1 image
const [file, setFile] = useState(null);
const handleUpload = (e) => {
setFile(e.target.files);
};
<input
type="file"
onChange={(e) => handleUpload(e)}
ref={fileInputRef}
multiple
/>
this was work if i select 2 or more files at once.
however i want to handle after choosing 1 image. user will be upload using the same input.
i have tried using method below and created error TypeError: file is not iterable
const handleUpload = (e) => {
setFile([...files, e.target.files]);
};
or
const handleUpload = (e) => {
let filesArray = file;
if (file) {
for (var i = 0; i < file.length; i++) {
filesArray.push(e.target.files[i]);
}
}
setFile(filesArray);
};
do you guys have any solution?
You should first set the default value for file as an array in your useState, then while using the set method you need to use the spread (...) operator properly. This will resolve your error TypeError: file is not iterable
Below are the changes that you will need to perform.
export default function InputComponent() {
const [file, setFile] = React.useState([]);
const handleUpload = (e) => {
setFile([...file, ...e.target.files]);
};
return (
<div>
<input type="file" onChange={(e) => handleUpload(e)} multiple /><br/><br/>
<textarea value={file}/>
</div>
);
}
Related
In react
const allInputs = { imgUrl: '' };
const [imageAsFile, setImageAsFile] = useState('');
const [imageAsUrl, setImageAsUrl] = useState(allInputs);
const [media, setMedia] = useState(null);
const handleImageAsFile = (e) => {
const image = e.target.files[0]
setImageAsFile(imageFile => (image));
console.log(imageAsFile);
}
Here is the input code, when I click this button, all types of files show, but I want to be able to store the type of file it is in a variable
<input type="text"
id="phone"
onChange={(e) => setPhone(e.target.value)}
/>
For example, if I select an image, how can know the type of image I have selected? If it is png or jpg or whatever before uploading it to the database.
First, React Javascript works the exact way Javascript works everywhere, For accessing the image type refer to the below code, I have added the comments for better understanding.
const [imageAsFile, setImageAsFile] = useState('');
const [imageAsUrl, setImageAsUrl] = useState(allInputs);
const [media, setMedia] = useState(null);
const handleImageAsFile = (e) => {
//image var holds the file object which has a type property
const image = e.target.files[0];
console.log(image.type); // this will output the mime, i.e "image/png" or "image/jpg"
setImageAsFile(imageFile => (image));
console.log(imageAsFile);
}
So I am working on my React app and a one point i need to upload some files. So I simply used the input file to make it work. I set its display none as I wanted my attachment icon to be clicked when wanting to upload the file.
Problem : Using the ref method, everything is working fine except one thing and that is below in my hangleFileChange function, when the setFiles() set the file variable, the component is not rendered and I do not see the file array. but if I do the file saving simply like
setFile(event.target.files[0])
I can see the rendering . But with the below code, the component is not rendering
import React, { useRef, useState } from "react";
const App = () => {
const fileInput = useRef(null);
const [file, setFile] = useState([]);
const handleClick = () => {
fileInput.current.click();
};
const handleFileChange = (event) => {
console.log("Make something");
let newFiles = file;
newFiles.push(event.target.files[0]);
console.log(newFiles);
setFile(newFiles);
};
// This should run on every render
console.log("the files array is ", file);
return (
<div className="patientactions-container">
<input
type="file"
style={{ display: "none" }}
onChange={(e) => handleFileChange(e)}
ref={fileInput}
/>
<div onClick={() => handleClick()}>clck</div>
</div>
);
};
export default App;
Please help.
Sandbox : https://codesandbox.io/s/kind-breeze-czc3w?file=/src/App.js:0-692
Try this version
const handleFileChange = (event) => {
console.log("Make something");
// Set the ne variable to an array, not file
let ne = [];
ne.push(event.target.files[0]);
// then set it equals file.
ne = file;
console.log(ne);
console.log(file);
setFile(file);
};
You can fix the code like this below.
import React, { useRef, useState } from "react";
const App = () => {
const fileInput = useRef(null);
const [file, setFile] = useState(null);
const handleClick = () => {
fileInput.current.click();
};
const handleFileChange = (nfile) => {
console.log("Make something");
if (file == null) setFile([nfile]);
else setFile([...file, nfile]);
};
console.log("the files array", file);
return (
<div className="patientactions-container">
<input
type="file"
style={{ display: "none" }}
onChange={(e) => handleFileChange(e.target.files[0])}
ref={fileInput}
/>
<div onClick={() => handleClick()}>clck</div>
</div>
);
};
export default App;
I'd have put this in the comments but my rep is not high enough.
I had a problem with rendering changes to an array, because arrays use pointers it did not "register" a state change that was enough to cause a render. Using the spread operator in your solution affected the pointer and thus a render occurred.
In my own solution I set my array to null before adding content and that worked fine for my problem.
FilePond onupdatefiles method is called two times.
As seen in the photo, two of the same file is selected. How can I prevent this?
React code
<Form className='orange-color ml-2'>
<FilePond
ref={ref => (ref)}
allowFileEncode={true}
allowMultiple={false}
oninit={() =>
console.log("FilePond "+formKey.toString()+" has initialised")
}
onupdatefiles={(fileItems) => {
const file = fileItems.map(fileItem => fileItem.file)
if (file[0]) {
const reader = new FileReader();
reader.readAsDataURL(file[0]);
reader.onload = (event) => {
const convertedResult = event.target.result
if (convertedResult) {
const regex = '(.*)(base64,)(.*)';
const matches = convertedResult.match(regex);
const val = matches[3];
changeSelected(val)
}
};
}
}
}
/>
I'm trying to upload a picture using react hooks
const [picture, setPicture] = useState();
const onChangePicture = e => {
console.log('picture: ', picture);
setPicture(...picture, e.target.files[0]);
};
<input
type="file"
//style={{ display: 'none' }}
onChange={e => onChangePicture(e)}
/>
however I'm getting the following error:
Uncaught TypeError: picture is not iterable
when I change the onChangePicture to
setPicture(picture, e.target.files[0])
the picture variable is undefined,
any help would be appreciated.
I think you meant to do:
setPicture([...picture, e.target.files[0]]);
This will concatenate the first file to all current files.
Remember to use const [picture, setPicture] = useState([]); as to make sure it doesn't break the first time around
For anybody arriving here looking for how to do it with TypeScript:
const [file, setFile] = useState<File>();
const onChange = (event: React.FormEvent) => {
const files = (event.target as HTMLInputElement).files
if (files && files.length > 0) {
setFile(files[0])
}
}
You can pass the value directly into setPicture function to set the state variable picture.
Try:
const [picture, setPicture] = useState(null);
const onChangePicture = e => {
console.log('picture: ', picture);
setPicture(e.target.files[0]);
};
<input
type="file"
//style={{ display: 'none' }}
onChange={onChangePicture}
/>
onChange = {(e) => this.onChangePicture(e)} can only be written when you made the states as
states = {
image,
name
}
but when using useState()
you need to use
const [image, setImage] = useState("");
onChange = {(e) => setImage(e.target.files[0])}
I hope this solves the error.
I finally fix this issue:
Problem is here
const [picture, setPicture] = useState(null); //Incorrect
You can use this
const [picture, setPicture] = React.useState(""); //Correct
This can fix this issue
using react js I need multiple image upload to firebase I tried with below code is not working to multiple upload.
//display multi
handleChange(event) {
const file = Array.from(event.target.files);
this.setState({ file });
}
//upload multi
fileuploadHandler = () => {
const storageRef = fire.storage().ref();
storageRef.child(`images/${this.state.file.name}`)
.putFile(this.state.file).then((snapshot) => {
});
}
render() {
return (
<div className="App">
<input id="file" type="file" onChange={this.handleChange.bind(this)} required multiple />
<button onClick={this.fileuploadHandler}>Upload!</button>
</div>
)
}
To handle multiple files, you'll need to loop over the files property of the input.
So:
const storageRef = fire.storage().ref();
this.state.file.forEach((file) => {
storageRef
.child(`images/${file.name}`)
.putFile(file).then((snapshot) => {
})
});