Gereksinimler ve Ön Hazırlık
Projeye başlamadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. React 19 ve üzeri sürümlerle birlikte gelen yeni nesil hooks ve performans iyileştirmelerini temel alacağız.
- Node.js (LTS sürümü, 20.x veya üzeri)
- npm veya pnpm paket yöneticisi
- Temel React bilgisi (Hooks, State Management, Props)
- Axios (HTTP istekleri için standart kütüphane)
Projenizi oluşturmak için terminalinizde şu komutu çalıştırın:
npx create-react-app dosya-yukleme-paneli --template typescript
cd dosya-yukleme-paneli
npm install axios
TypeScript kullanımı, dosya yükleme süreçlerinde veri tiplerini (File, Blob, ProgressEvent) daha iyi yönetmenizi sağlayarak çalışma zamanı hatalarını minimize eder.
Dosya Yükleme Bileşeninin Temel Yapısını Oluşturma
Dinamik bir panel, kullanıcının seçtiği dosyayı anlık olarak görüntüleyebilmeli ve yükleme sürecini takip edebilmelidir. İlk adım olarak basit bir input yapısı ve state yönetimi kuracağız.
import React, { useState } from 'react';
const DosyaYukleyici = () => {
const [secilenDosya, setSecilenDosya] = useState(null);
const dosyaDegisimHandler = (e: React.ChangeEvent) => {
if (e.target.files && e.target.files[0]) {
setSecilenDosya(e.target.files[0]);
}
};
return (
{secilenDosya && Seçilen: {secilenDosya.name}
}
);
};
Bu kod bloğu, kullanıcının seçtiği dosyayı React state'inde tutar. onChange olayı, dosya seçildiği anda tetiklenir ve e.target.files üzerinden ilgili dosyaya erişmemizi sağlar.
Dinamik Sürükle ve Bırak Özelliği Ekleme
Kullanıcı deneyimini iyileştirmek için sadece tıklama ile değil, sürükle-bırak yöntemiyle de dosya kabul etmeliyiz. Bunun için onDragOver ve onDrop olaylarını kullanacağız.
const surukleBrakHandler = (e: React.DragEvent) => {
e.preventDefault();
if (e.dataTransfer.files && e.dataTransfer.files[0]) {
setSecilenDosya(e.dataTransfer.files[0]);
}
};
// JSX içerisinde:
e.preventDefault()}
onDrop={surukleBrakHandler}
style={{ border: '2px dashed #ccc', padding: '20px' }}
>
Dosyaları buraya sürükleyin
Burada e.preventDefault() kullanımı hayati önem taşır; çünkü tarayıcıların varsayılan davranışı, sürüklenen dosyayı yeni bir sekmede açmaya çalışmaktır. Bu davranışı engelleyerek kendi mantığımızı çalıştırıyoruz.
Axios İle Dosya Yükleme ve İlerleme Takibi
Dosyayı sunucuya gönderirken FormData nesnesini kullanmalıyız. Ayrıca, büyük dosyaların yüklenme sürecini kullanıcıya göstermek için Axios'un onUploadProgress özelliğinden faydalanacağız.
const yukle = async () => {
if (!secilenDosya) return;
const formData = new FormData();
formData.append('file', secilenDosya);
await axios.post('/api/upload', formData, {
onUploadProgress: (progressEvent) => {
const yuzde = Math.round((progressEvent.loaded * 100) / (progressEvent.total || 1));
console.log(`Yükleme: ${yuzde}%`);
}
});
};
Bu yöntem, sunucu tarafında dosyanın doğru bir şekilde işlenmesini sağlar. Sunucu, multipart/form-data başlığını (header) otomatik olarak tanıyacaktır.
Dosya Yükleme Yöntemlerinin Karşılaştırılması
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Standard Input | Basit ve tarayıcı uyumlu | Gelişmiş UX eksikliği |
| Drag & Drop API | Modern ve kullanıcı dostu | Karmaşık olay yönetimi |
| Tus.io (Resumable) | Büyük dosyalar için kesintisiz | Ekstra kütüphane bağımlılığı |
Güvenlik Uyarısı: Sunucu tarafında dosya türünü (MIME type) ve dosya boyutunu mutlaka kontrol edin. Sadece istemci tarafındaki (client-side) kontroller yeterli değildir; kötü niyetli kullanıcılar bu kontrolleri kolayca atlatabilir. Dosyaları sunucuda isimlendirirken orijinal isimlerini kullanmayın, benzersiz ID'ler (UUID) atayın.
Dosya Güvenliği ve Doğrulama
Dosya yükleme paneli yaparken en büyük risk, zararlı dosyaların (script dosyaları, executable) sunucuya yüklenmesidir. İstemci tarafında şu kontrolleri eklemek iyi bir pratiktir:
const dosyaKontrol = (file: File) => {
const izinVerilenTipler = ['image/jpeg', 'image/png', 'application/pdf'];
if (!izinVerilenTipler.includes(file.type)) {
alert('Geçersiz dosya formatı!');
return false;
}
if (file.size > 5 * 1024 * 1024) { // 5MB limit
alert('Dosya boyutu çok büyük!');
return false;
}
return true;
};
Sıkça Sorulan Sorular
React ile çoklu dosya yükleme nasıl yapılır?
Input elementine multiple niteliğini ekleyerek ve state içerisinde File[] array yapısını kullanarak çoklu dosya seçimi ve yüklemesi yapabilirsiniz.
Yükleme sırasında hata oluşursa ne yapmalıyım?
Axios try-catch blokları kullanarak hata durumunda kullanıcıya anlamlı mesajlar gösterin ve yükleme işlemini durdurun.
Neden FormData kullanmalıyız?
FormData, ikili (binary) verileri HTTP üzerinden sunucuya göndermek için kullanılan standart bir web API'sidir ve dosya yükleme işlemlerinde zorunludur.
Büyük dosyalar için en iyi yöntem nedir?
Büyük dosyalar için "Chunking" (parçalara bölme) yöntemini kullanmalısınız. Dosyayı küçük parçalara ayırıp sırayla yüklemek, kesintilerde işlemin baştan başlamasını önler.
Yüklenen dosyaların güvenliğini nasıl sağlarım?
Dosyaları public klasör yerine, doğrudan erişilemeyen (private) bir dizinde saklayın ve erişim için geçici imzalı URL'ler (signed URLs) oluşturun.
Dosya Yükleme Süreçlerinde Performans Optimizasyonu
Büyük boyutlu dosyaların yüklenmesi, hem istemci tarafında tarayıcıyı yorabilir hem de sunucu tarafında zaman aşımı (timeout) hatalarına yol açabilir. Bu süreci optimize etmek için "Chunked Upload" (Parçalı Yükleme) yöntemini kullanmak en profesyonel yaklaşımdır. Dosyayı küçük parçalara bölerek yüklemek, ağ kesintilerinde tüm işlemi baştan başlatmak yerine sadece başarısız olan parçayı tekrar göndermenize olanak tanır.
Aşağıdaki örnek, bir dosyanın 1MB'lık parçalara nasıl bölünebileceğini göstermektedir:
const uploadInChunks = async (file) => {
const CHUNK_SIZE = 1024 * 1024; // 1MB
const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
for (let i = 0; i < totalChunks; i++) {
const start = i * CHUNK_SIZE;
const end = Math.min(start + CHUNK_SIZE, file.size);
const chunk = file.slice(start, end);
const formData = new FormData();
formData.append('chunk', chunk);
formData.append('index', i);
formData.append('fileName', file.name);
await axios.post('/api/upload-chunk', formData);
}
};
Yükleme Paneli İçin Gelişmiş Hata Ayıklama Stratejileri
Dosya yükleme süreçleri, ağ hataları, sunucu kısıtlamaları veya dosya sistemi izinleri gibi birçok noktada başarısız olabilir. Kullanıcıya "Bir hata oluştu" demek yerine, hatanın kaynağını belirten spesifik geri bildirimler sunmalısınız. İşte hata yönetimi için kullanabileceğiniz bir yapı:
Hata Kodlarını Yakalama
Axios interceptor'larını veya try-catch bloklarını kullanarak sunucudan dönen hata kodlarını sınıflandırın:
try {
await axios.post('/upload', data);
} catch (error) {
if (error.response) {
// Sunucu yanıt verdi (4xx veya 5xx)
switch (error.response.status) {
case 413:
alert("Dosya boyutu sunucu limitlerini aşıyor.");
break;
case 415:
alert("Desteklenmeyen dosya formatı.");
break;
default:
alert("Sunucu hatası: " + error.response.status);
}
} else if (error.request) {
// İstek gönderildi ama yanıt alınamadı (Network hatası)
alert("İnternet bağlantınızı kontrol edin.");
}
}
Test Edilebilirlik ve Mock Servisler
Yükleme panelinizi test ederken gerçek bir sunucuya ihtiyaç duymadan, msw (Mock Service Worker) gibi kütüphanelerle ağ katmanını simüle edebilirsiniz. Bu, özellikle yavaş ağ koşullarını (slow 3G) test etmek ve yükleme çubuğunun (progress bar) doğru çalışıp çalışmadığını doğrulamak için kritiktir.
| Senaryo | Test Edilecek Durum |
|---|---|
| Yavaş Bağlantı | Progress bar'ın %0'dan %100'e akıcılığı |
| İptal Etme | AbortController ile isteğin durdurulması |
| Dolu Disk | Sunucu tarafı 507 (Insufficient Storage) hatasının yönetimi |
Sonuç
React ile dinamik bir dosya yükleme paneli geliştirmek, doğru araçları ve güvenlik prensiplerini bir araya getirmeyi gerektirir. Bu rehberde, temel bir yapıdan başlayarak sürükle-bırak, ilerleme takibi ve dosya doğrulama süreçlerini ele aldık. Bir sonraki adım olarak, yüklenen dosyaların önizlemesini (preview) oluşturmak için URL.createObjectURL metodunu inceleyebilir ve kullanıcı deneyimini daha da zenginleştirebilirsiniz.
Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce, sunucu tarafındaki güvenlik duvarı (WAF), dosya tarama (antivirus) ve yetkilendirme katmanlarını mutlaka yapılandırınız.
Yorumlar (0)
Yorum Yaz