score:2

Accepted answer

edit still-sea-ijvrk


you can't programmatically set the value of an input with type="file" for security reasons.

<input
  ...
  type="file"
  onchange={uploadimg}
  // remove the value prop
/>

in the readfileasync function, you need to account for the multiple files that will come, so instead we pass one file to it.

you were concatenating the result of the filereader to get a valid base64 string, but you can just use filereader#readasdataurl. and that function will return the base64 string for the image.

function readfileasync(file) {
  ...
    reader.onload = () => {
      resolve({
        id: uuid(),
        url: reader.result,
        type: "image",
      });
    };
    reader.onerror = reject;
    reader.readasdataurl(file);
  });
}

and in the uploadimg function,

async function uploadimg(e) {
  const file = e.target.files[0];
  if (file) {
    setimage([...images, (await readfileasync(file))]);
    setfiles([...files, file]);
  }
}

in the deletefiles function, now we have to update the image and files states.

because in the files state, the images aren't recorded by anything unique, so we use the insert position (from the uploadimg function) to match the files and remove the one to delete.

function deletefile(id) {
  const imageindex = images.findindex(item => item.id === id);

  if (imageindex > -1) {
    setimages(images.filter(item => item.id !== id));
    setfiles(files.filter((_, i) => i !== imageindex));
  }
}

}


for the saving

there isn't a need for for the react-hook-form package, since the input with type="file"'s value cannot be set programmatically.

so if it's the files from the input you want to access

  • you can use a ref to access it
  • store the file in another state
  • use the base64 strings you generated.

i used another state to hold the files in the codesandbox, but you can use any of the three options.


Related Query

More Query from same tag