0

Problem

I'm on working with React on Chrome, and to upload a file I use <input type="file" />. However, the first upload never works, but the subsequent uploads have absolutely no problems.

Edit: When I talk about the upload, I'm referring to the value of my useState pictureFile, which is always false when I first send a picture file. I'm really sorry for not being clear...

Trials

To tell you the truth, I really don't know where to begin to deal with this problem...

I first tried to delete the onClick, which is used to deal with the upload of the same file. But it has no effects. And I also tried some solutions found in an old Stack Overflow post but there are still no results.

Code

Below it's my code:

import { useState } from "react";

function Settings() {
  let [pictureFile, setPictureFile] = useState(false);

  const updateAvatar = (event) => {
    if (event.target.files && event.target.files.length > 0) {
      setPictureFile(event.target.files[0]);
    }
    console.log(pictureFile);
  };

  return (
    <div id="settingsContainer">
      <input
        type="file"
        accept=".png, .jpeg, .jpg, .gif"
        name="user_pictureURL"
        id="user_pictureURL"
        onChange={updateAvatar}
        onClick={event => event.target.value = null}
      />
    </div>
  );
}

export default Settings;

I thank in advance anyone who will take the time to help me :D.

Heraxia
  • 89
  • 6
  • 1
    Where is the `form` element that wraps this input? You will need an `enctype` on the form: https://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean#:~:text=use%20multipart/form%2Ddata%20when%20your%20form%20includes%20any%20%3Cinput%20type%3D%22file%22%3E%20elements – Harrison Jul 14 '23 at 09:47

2 Answers2

1

Do you want to see preview of your image? Or Just send it to the server?

set preview image :

const [file, setFile] = useState("");

const updateAvatar = (event: any) => {
  if (event.target.files && event.target.files.length > 0) {
    const file: any = event.target.files[0];
    setFile(URL.createObjectURL(file));
  }
};

return (
   <div id="settingsContainer">
      <img src={file} />
      <input
        type="file"
        accept=".png, .jpeg, .jpg, .gif"
        name="user_pictureURL"
        id="user_pictureURL"
        onChange={updateAvatar}
      />
  </div>
)

Send it to the server

  onFileUpload = () => {
 
        // Create an object of formData
        const formData = new FormData();
 
        // Update the formData object
        formData.append(
            "myFile",
            this.state.selectedFile,
            this.state.selectedFile.name
        );
 
        // Details of the uploaded file
        console.log(this.state.selectedFile);
 
        // Request made to the backend api
        // Send formData object
        axios.post("api/uploadfile", formData);
};

More details :

1

This is because the changes using useState will not reflect in the current context, the next time it works because it shows the previous context (the previously uploaded file) if you observe carefully while uploading different files.

This is common behaviour of useState, for more information go to the link

Kunal Khivensara
  • 1,619
  • 14
  • 21
  • I really didn't know about that! Thank you very much for informing me :D. I didn't think my problem could come from the `useState`. As for seeing it with the file's names... well I didn't really look at them as their name are a long string of random numbers and letters... – Heraxia Jul 14 '23 at 10:07
  • @Heraxia no worries, if you find it useful please accept the answer. – Kunal Khivensara Jul 14 '23 at 10:26