akano1
akano1

Reputation: 41614

how to put a file in state variable with react hooks

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.

Upvotes: 5

Views: 27547

Answers (5)

GG.
GG.

Reputation: 21834

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])
    }
}

Upvotes: 11

Sourabh
Sourabh

Reputation: 253

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.

Upvotes: 0

vim kndll
vim kndll

Reputation: 19

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

Upvotes: -2

Raman Kishore
Raman Kishore

Reputation: 582

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}
/>

Upvotes: 7

apokryfos
apokryfos

Reputation: 40653

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

Upvotes: 10

Related Questions