0

Please review my code first.

const test = () => {

const [files, setFiles] = useState ([]);

//I think I have to edit following statement.

const handleFile = (e) => {
   const newFiles = []
   for (let i=0; i < e.target.files.length; i++) {
       newFiles.push(e.target.files[i])
    }
        setFiles(newFiles)
};

return (

   {files.map((file, index) => (
     <div>
       <div key={index}>
         <p>
         {file.name}
         </p>
         <Button size='small' onClick={() => {deleteSelectedFile(file.name)}}>
         Delete
         </Button>
       </div>
     </div>
    ))}

    <div>
        <label onChange={handleFile}>
            <input type='file' multiple />+ Attach File
        </label>
    </div>

)

}

with handleFile statement, I can appropriately get the files.

However, when I upload one file at a time and then upload one file again,

the file is not added. the file replaces file.

There is not problem when I upload multiple time at once.

For example, I upload 'hello.jpg', and it renders well in the screen. Then, I upload 'goodbye.jpg', it renders well, but 'goodbye.jpg' replaces 'hello.jpg'.

Therefore, what I see is just 'goodbye.jpg' [button], not

'hello.jpg' [button] 'goodbye.jpg' [button]

.

I want my files to stacked up, without replacing.

I need some wisdom!

2 Answers 2

1

In my opinion, you only need to spread the prev state values and the files during the change event.

import { useState } from "react";

export default function App() {
  const [files, setFiles] = useState([]);

  const handleChange = (e) => {
    // This is what you need
    setFiles((prev) => [...prev, ...Object.values(e.target.files)]);
  };

  return (
    <div>
      <label onChange={handleChange}>
        <input type="file" multiple />
      </label>
      {files.map((file) => {
        return <p>{file.name}</p>;
      })}
    </div>
  );
}
Sign up to request clarification or add additional context in comments.

2 Comments

Wow. this works so well. Can you tell me little more how your statement works? I'm totally lost but so glad it works. Thank you so much!
You can use a function inside the setState function to get the current state value and return whatever you want to replace the state. What you want here is the current value of the state + the value you added. So, you just need to return the merged arrays => [prev, current]
0

how about you don't create a new variable for new files, you just set the state for the files since it's an array

setFiles(oldFile => [...oldFile,e.target.files[i]]);

If it's possible you can drop a codepen link

2 Comments

Thank you so much. I learned a lot. I never thought about this way.
sure , you are welcome

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.