When creating a product I use React-Dropzone but when editing I intend to use it in the same way. I would like that when editing the product, the images that are already uploaded to the product are displayed under React-Dropzone so that the user can delete them all, or just one, etc.
This code works fine when uploading images, but when I pass the array with the images that already have the product in the database at the time of editing, it shows me the empty image preview:
import React from 'react';
import {useDropzone} from 'react-dropzone'
import { useState, useEffect } from 'react'
const DragAndDrop = ({files, setFiles, setDropError }) => {
console.log(files); //Array of images that the product already has in the database
const onDropRejected = () => {
setDropError('Imágenes con tamaño Máximo de 1MB')
setTimeout(() => {
setDropError('')
}, 3000)
}
const {
acceptedFiles,
fileRejections,
getRootProps,
getInputProps
} = useDropzone({
accept: {
'image/jpeg': [],
'image/jpg': [],
'image/png': []
},
maxFiles:3,
maxSize:1000000,
onDropRejected,
onDropAccepted: acceptedFiles => {
console.log(acceptedFiles);
if (files.length<1){
setFiles(acceptedFiles.map(file =>
Object.assign(file, {
preview: URL.createObjectURL(file)
})));
} else {
setFiles(files.map(file =>
Object.assign(file, {
preview: URL.createObjectURL(file) //Here I try to pass the images to create the preview but the images are not shown
})));
}
}
})
...
How can I accomplish this task? Thank you.
Solution:
import React from 'react';
import {useDropzone} from 'react-dropzone'
import { useState, useEffect } from 'react'
const DragAndDrop = ({files, setFiles, setDropError, totalFiles }) => {
//const [files, setFiles] = useState([])
const onDropRejected = () => {
setDropError('Hasta 3 imágenes. máximo 2 MB')
setTimeout(() => {
setDropError('')
}, 3000)
}
const {
acceptedFiles,
fileRejections,
getRootProps,
getInputProps
} = useDropzone({
accept: {
'image/jpeg': [],
'image/jpg': [],
'image/png': []
},
maxFiles:3,
maxSize:2000000,
onDropRejected,
onDropAccepted: acceptedFiles => {
setFiles(acceptedFiles.map(file =>
Object.assign(file, {
preview: URL.createObjectURL(file)
})));
}
})
const removeFile = file => () => {
const newFiles = [...files]
newFiles.splice(newFiles.indexOf(file), 1)
setFiles(newFiles)
}
const removeAll = () => {
setFiles([])
}
const thumbs = files.map(file => (
<div key={file.name}>
<button onClick={removeFile(file)} className="text-center hover:bg-blue-200 absolute rounded">
<span className='p-2 text-center text-lg'>x</span>
</button>
<div className='w-32'>
<img
src={file.preview}
// Revoke data uri after image is loaded
onLoad={() => { URL.revokeObjectURL(file.preview) }}
/>
</div>
</div>
))
useEffect(() => {
// Make sure to revoke the data uris to avoid memory leaks, will run on unmount
return () => files.forEach(file => URL.revokeObjectURL(file.preview));
}, []);
const acceptedFileItems = acceptedFiles.map(file => (
<li key={file.path}>
{file.path} - {file.size} bytes
</li>
));
const fileRejectionItems = fileRejections.map(({ file, errors }) => {
return (
<li key={file.path}>
{file.path} - {file.size} bytes
<ul>
{errors.map(e => <li key={e.code}>{e.message}</li>)}
</ul>
</li>
)
});
return (
<section className={`container mt-6`}>
<div {...getRootProps({ className: 'dropzone' })}
className={`flex flex-col w-full border-2 border-cyan-600 border-dashed p-4 cursor-pointer ${ files.length === 3 || totalFiles && totalFiles.length === 3 && 'pointer-events-none' }`}>
<input {...getInputProps()} />
{
files.length === 3 || totalFiles && totalFiles.length === 3 ? (
<div className='flex justify-center'>
<div className=' text-center gap-2 mb-2'>
<p>Deshabilitado - Máximo 3 imágenes</p>
</div>
</div>
) : (
<div className='text-center gap-2 mb-2'>
<p>Arrastra y suelta imágenes o selecciona dando click</p>
<em className='text-xs'>(Máximo 3 imágenes, .jpg, .png)</em>
</div>
)
}
</div>
<aside className='text-xs mt-4'>
{files.length === 3 && <div>{files.length}</div>}
{/* <h4>Archivos Correctos</h4>
<ul>{acceptedFileItems}</ul>
<h4>Archivos con error</h4>
<ul>{fileRejectionItems}</ul> */}
<div className="flex gap-4 justify-center">
{thumbs}
</div>
</aside>
{files.length > 0 && <button onClick={removeAll} className="btn btn-xs text-xs mt-4 btn-ghost">Eliminar</button>}
</section>
);
}
export default DragAndDrop