简体   繁体   中英

Add multiple files with onChange function and React Hooks, but singly

I need to add to files with react components. Here how I'm doing it with one file(onChange and onSubmit functions):

const onChangeFile = e => {
    setFileData(e.target.files[0]);
  };

const onSubmit = e => {
    e.preventDefault();

    const newItem = new FormData();
    newItem.append('item', fileData);

    const { description } = offerData;

    newItem.append('description', description);

    addItem(newItem);

    setFileData(null);
  }

Input(reactstrap):

<CustomInput
     type="file"
     name="item" id="item" label="Choose item image..."
     onChange={onChangeFile}
/>

And here, how I'm doing it with multiple files, but with one input:

const onChangeFile = e => {
    setFileData(e.target.files);
  };

const onSubmit = e => {
    e.preventDefault();
    const newItem = new FormData();
    for (const key of Object.keys(fileData)) {
      newItem.append('item', fileData[key])
    }

    const { description1, description2 } = item;

    newItem.append('description1', description1);
    newItem.append('description2', description2);

    addItem(newItem);
    setFileData(null);
  }

and input:

<CustomInput
     type="file"
     name="item"
     id="item"
     multiple
     label="Add images/image..."
     onChange={onChangeFile}
/>

And both works, but this time I want to add multiple files( two exactly), with two single inputs and my useState hook doesn't work(like that it isn't iterable). Here's how it looks like for both ways.

const [fileData, setFileData] = useState(null);

So, how to add one object with two images, but added with two single inputs?

Not sure if I fully understand. So the way you have it now you have a single input to receive data, however you want to be able to update your state from two inputs?

When you are setting state you are doing:

const onChangeFile = e => {
    setFileData(e.target.files);
};

If this same handler is hooked up to another input, the second set of files will just override the first.

If you want to keep adding to your state you could either use an object, or an array. So onChange could look something like this:

const onChangeFile = e => {
    // assuming here that e.target.files is an array already
    const filesToAdd = e.target.files;
    setFileData([...filesData, ...filesToAdd]);
};

Or with an object

const onChangeFile = e => {
    const filesToAdd = e.target.files.reduce(
                         (map, file) => ({..., [file.name]: file}), {}));
    const filesDataUpdate = {
         ...filesData,
         ...filesToAdd
    }
    setFileData(filesDataUpdate);
};

In this case I am assuming each file has a unique name. You could key it with any unique value.

Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM