đŁ
TĂ©lĂ©chargement dâun seul fichier
Pour télécharger un seul fichier dans React, vous devez définir le content-type
et content-length
en-tĂȘtes et indiquez le contenu du fichier comme corps de la requĂȘte :
import { ChangeEvent, useState } from 'react';
function FileUploadSingle() {
const [file, setFile] = useState<File>();
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
if (e.target.files) {
setFile(e.target.files[0]);
}
};
const handleUploadClick = () => {
if (!file) {
return;
}
// đ Uploading the file using the fetch API to the server
fetch('https://httpbin.org/post', {
method: 'POST',
body: file,
// đ Set headers manually for single file upload
headers: {
'content-type': file.type,
'content-length': `${file.size}`, // đ Headers need to be a string
},
})
.then((res) => res.json())
.then((data) => console.log(data))
.catch((err) => console.error(err));
};
return (
<div>
<input type="file" onChange={handleFileChange} />
<div>{file && `${file.name} - ${file.type}`}</div>
<button onClick={handleUploadClick}>Upload</button>
</div>
);
}
export default FileUploadSingle;
- Tout dâabord, nous ajoutons un
input
élément avectype="file"
attribut. - Nous pouvons stocker le fichier sĂ©lectionnĂ© dans lâĂ©tat du composant React, aprĂšs lâavoir reçu du
onChange
Ă©vĂ©nement. Comme nous ne pouvons sĂ©lectionner quâun seul fichier, nous pouvons lâobtenir Ă partir dufiles
tableau sur lâentrĂ©e :e.target.files[0]
. - Nous pouvons tĂ©lĂ©charger le fichier Ă lâaide de lâAPI Fetch. Nous devons dĂ©finir lâensemble
body
au fichier que nous avons reçu de lâentrĂ©e et des en-tĂȘtes :content-type
au dossiertype
et lecontent-length
pourfile.size
. Notez que les en-tĂȘtes doivent ĂȘtre des valeurs de chaĂźne.
Jâai utilisĂ© une API httpbin.org qui accepte les tĂ©lĂ©chargements de fichiers et rĂ©pond avec une copie de la demande que vous envoyez. Voici le rĂ©sultat :
Téléchargement de plusieurs fichiers
Pour télécharger plusieurs fichiers à partir de input
Ă©lĂ©ment dans React, vous devez utiliser lâAPI JavaScript FormData et encoder la demande comme multipart/form-data
.
import { ChangeEvent, useState } from 'react';
function FileUploadMultiple() {
const [fileList, setFileList] = useState<FileList | null>(null);
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
setFileList(e.target.files);
};
const handleUploadClick = () => {
if (!fileList) {
return;
}
// đ Create new FormData object and append files
const data = new FormData();
files.forEach((file, i) => {
data.append(`file-${i}`, file, file.name);
});
// đ Uploading the files using the fetch API to the server
fetch('https://httpbin.org/post', {
method: 'POST',
body: data,
})
.then((res) => res.json())
.then((data) => console.log(data))
.catch((err) => console.error(err));
};
// đ files is not an array, but it's iterable, spread to get an array of files
const files = fileList ? [...fileList] : [];
return (
<div>
<input type="file" onChange={handleFileChange} multiple />
<ul>
{files.map((file, i) => (
<li key={i}>
{file.name} - {file.type}
</li>
))}
</ul>
<button onClick={handleUploadClick}>Upload</button>
</div>
);
}
export default FileUploadMultiple;
La premiĂšre diffĂ©rence par rapport Ă notre exemple de tĂ©lĂ©chargement de fichier unique est lâajout de multiple
attribut sur le input
élément.
Au lieu de stocker un seul fichier dans lâĂ©tat du composant React, nous enregistrons lâensemble FileList
en état
đŁ
Notez que le FileList
nâest pas un tableau, nous ne pouvons donc pas utiliser des mĂ©thodes de tableau rĂ©guliĂšres comme map
ou forEach
. Cependant, nous pouvons toujours accéder aux membres par index fileList[0]
parcourez les fichiers en utilisant for..of
ou les répandre.
Pour télécharger plusieurs fichiers :
- Créer un
FormData
objet:const data = new FormData()
; - Ajoutez chaque fichier que vous souhaitez tĂ©lĂ©charger Ă lâaide de FormData.append() â il accepte un nom de champ de formulaire, le fichier et un nom de fichier comme paramĂštres.
- Ă lâaide de lâAPI Fetch, tĂ©lĂ©chargez les fichiers en dĂ©finissant les donnĂ©es du formulaire comme
body
. Notez que lorsque vous utilisez des donnĂ©es de formulaire, vous nâavez pas besoin de dĂ©finir les en-tĂȘtes manuellement. Il est pris en charge par lâAPI de rĂ©cupĂ©ration.
Voici à quoi ça ressemble :
Personnalisation de lâentrĂ©e du fichier
Le défaut input
LâĂ©lĂ©ment nâoffre pas grand-chose en termes de style. Pour crĂ©er une entrĂ©e de tĂ©lĂ©chargement de fichier personnalisĂ©e dans React, vous devrez masquer lâentrĂ©e de tĂ©lĂ©chargement de fichier natif et dĂ©clencher le click
Ă©vĂ©nements sur lâentrĂ©e Ă lâaide de refs :
import { ChangeEvent, useRef, useState } from 'react';
function CustomFileInput() {
const [file, setFile] = useState<File>();
const inputRef = useRef<HTMLInputElement | null>(null);
const handleUploadClick = () => {
// đ We redirect the click event onto the hidden input element
inputRef.current?.click();
};
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
if (!e.target.files) {
return;
}
setFile(e.target.files[0]);
// đ© do the file upload here normally...
};
return (
<div>
<div>Upload a file:</div>
{/* đ Our custom button to select and upload a file */}
<button onClick={handleUploadClick}>
{file ? `${file.name}` : 'Click to select'}
</button>
{/* đ Notice the `display: hidden` on the input */}
<input
type="file"
ref={inputRef}
onChange={handleFileChange}
style={{ display: 'none' }}
/>
</div>
);
}
Seulement le input
LâĂ©lĂ©ment avec le type de fichier peut ouvrir les fichiers Ă sĂ©lectionner dans le navigateur. Pour tĂ©lĂ©charger un fichier en cliquant sur le bouton personnalisĂ©, nous devons dĂ©clencher le click()
Ă©vĂ©nement sur lâentrĂ©e : inputRef.current?.click();
Si nous ne voulons pas afficher lâentrĂ©e native, nous pouvons la masquer en ajoutant le display: none
propriété CSS dans son style
ou en appliquant une classe CSS qui dĂ©finit la propriĂ©tĂ© dâaffichage sur none
(par exemple, dans Tailwind, le nom de la classe est hidden
).
DĂšs lors, vous pouvez enregistrer les fichiers sĂ©lectionnĂ©s dans lâĂ©tat ou les tĂ©lĂ©charger immĂ©diatement. Vous avez maintenant une personnalisation complĂšte de lâentrĂ©e de tĂ©lĂ©chargement de fichier :
Conclusion
Dans React, le téléchargement de fichiers est implémenté en utilisant le code HTML input
Ă©lĂ©ment et du JavaScript pour faire une requĂȘte POST/PUT au serveur avec le FormData qui contient les fichiers sĂ©lectionnĂ©s.
Votre serveur devra alors traiter les donnĂ©es du formulaire en plusieurs parties pour accepter les tĂ©lĂ©chargements de fichiers. Vous pouvez utiliser Multer dans Node.js pour implĂ©menter cela ou tĂ©lĂ©charger les fichiers directement sur Amazon S3 si câest ce que vous voulez.
Comme toujours, trouvez le code utilisé dans les exemples de mon référentiel GitHub.