ver la captura de pantalla
. ¿Por qué las imágenes se corrompen? Estoy tratando de cargar imágenes usando axois post pero axois post no puede procesar mis imágenes correctamente. Mi código dividido en dos partes. La primera parte donde escribo la lógica para cargar varias imágenes y la segunda parte la estoy usando en el componente de mi página.
primera parte
este código para cargar varias imágenes
export const MultiImageUpload = ({Setimage}) => {
const [selectedImages, setSelectedImages] = useState([]);
const onSelectFile = (event) => {
const selectedFiles = event.target.files;
const selectedFilesArray = Array.from(selectedFiles);
const imagesArray = selectedFilesArray.map((file) => {
return URL.createObjectURL(file);
});
setSelectedImages((previousImages) => previousImages.concat(imagesArray));
Setimage((previousImages) => previousImages.concat(imagesArray));
// FOR BUG IN CHROME
event.target.value = "";
};
function deleteHandler(image) {
setSelectedImages(selectedImages.filter((e) => e !== image));
Setimage(selectedImages.filter((e) => e !== image));
URL.revokeObjectURL(image);
}
segunda parte ahora estoy importando este componente en mi página
const AdsPost = ({data}) => {
const[image,Setimage] = useState([])
var data = new FormData();
image.forEach(file=>{
data.append("files", file)
console.log("image_url:",file)
})
let submit_ads = axios.post(url,data,{headers:headers}).then((res)=>{
console.log(res)
})
aquí está myjsx
<MultiImageUpload
Setimage={Setimage}/>
Puedo cargar una imagen con cartero, pero no sé por qué Axois Post no puede cargar imágenes.
Aquí está tu problema:
image.forEach(file=>{
data.append("files", file)
console.log("image_url:",file)
})
El file parámetros no es un archivo, pero es el resultado de
const imagesArray = selectedFilesArray.map((file) => {
return URL.createObjectURL(file); // <--- this line
});
En otras words, esencialmente estás haciendo
data.append("files", URL.createObjectURL(file));
Arregle eso y su código debería funcionar.
Aquí hay una caja de arena con una solución propuesta, la idea es delegar el estado de los archivos a un proveedor y usar el contexto en los componentes secundarios según sea necesario.
import { createContext } from "react";
export default createContext({
/** @return {{ file:File, dataUrl:string }[]]} */
get files() {
return [];
},
/** @return {Error[]} */
get errors() {
return [];
},
/** @param {File[]} files */
addFiles(files) {},
/** @param {File} file */
removeFile(file) {},
/** @param {Error[]} errors */
setErrors(errors) {}
});
import { useContext, useMemo, useState } from "react";
import FilesContext from "../context/files";
const FilesProvider = ({ children }) => {
const [internal, setInternal] = useState(() => ({
files: [],
errors: []
}));
const contextValue = useMemo(
() => ({
get files() {
return internal.files;
},
get errors() {
return internal.errors;
},
addFiles(filesAdded) {
setInternal(({ files, errors }) => ({
files: files.concat(
filesAdded.map((file) => ({
file,
dataUrl: URL.createObjectURL(file)
}))
),
errors
}));
},
removeFile(fileRemoved) {
URL.revokeObjectURL(fileRemoved);
setInternal(({ files, errors }) => ({
files: files.filter(({ file }) => file !== fileRemoved),
errors
}));
},
setErrors(errors) {
setInternal(({ files }) => ({ files, errors }));
}
}),
[internal]
);
return (
<FilesContext.Provider value={contextValue}>
{children}
</FilesContext.Provider>
);
};
const useFiles = () => useContext(FilesContext);
export default FilesProvider;
export { useFiles };
<FilesProvider>
<FilesSelectComponent />
</FilesProvider>
y
const { files, errors, addFiles, removeFile, setErrors } = useFiles();