Gereksinimler ve Ön Hazırlık
Uygulamaya başlamadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. 2026 yılı standartlarında React 19 veya üzeri sürümlerle çalışmanızı öneriyoruz. Projenizi oluşturmak için Vite gibi hızlı bir derleyici kullanmak, geliştirme sürecinizi optimize edecektir.
- Node.js (LTS sürümü)
- React 19+
- Temel JavaScript (ES6+ sözdizimi)
- CSS veya Tailwind CSS (Arayüz stilini yönetmek için)
Projenizi başlatmak için terminalinizde şu komutu çalıştırarak gerekli kurulumları yapabilirsiniz:
npm create vite@latest drag-drop-app -- --template react
cd drag-drop-app
npm install
Bu komutlar, modern bir React projesi iskeleti oluşturur ve gerekli bağımlılıkları yükler. Kurulum tamamlandıktan sonra npm run dev komutu ile geliştirme sunucusunu başlatabilirsiniz.
Sürükle Bırak Mantığı: Temel Olay Yakalayıcılar
Sürükle-bırak işlemleri, HTML5'in yerel Drag and Drop API'si üzerine kuruludur. React'te bu olayları yönetmek için onDragOver, onDragLeave ve onDrop olaylarını kullanırız. En kritik nokta, tarayıcının varsayılan davranışını (dosyayı yeni bir sekmede açma) engellemektir.
Aşağıdaki kod örneği, bir bileşenin sürükleme olaylarına nasıl tepki vereceğini gösterir:
const DropZone = () => {
const handleDragOver = (e) => {
e.preventDefault(); // Tarayıcının varsayılan dosya açma eylemini durdurur
};
const handleDrop = (e) => {
e.preventDefault();
const files = e.dataTransfer.files;
console.log("Sürüklenen dosyalar:", files);
};
return (
Dosyaları buraya sürükleyin
);
};
Bu kodda e.preventDefault() kullanımı hayati önem taşır. Eğer bu satırı yazmazsanız, tarayıcı sürüklediğiniz dosyayı doğrudan kendi penceresinde açmaya çalışacaktır.
Dosya Doğrulama ve Güvenlik Önlemleri
Kullanıcıların sisteme yüklediği dosyaları doğrudan kabul etmek güvenlik açıkları doğurabilir. Dosya türü (MIME type) ve dosya boyutu kontrolleri, hem sunucu yükünü azaltır hem de kötü niyetli dosyaların yüklenmesini engellemeye yardımcı olur.
const validateFile = (file) => {
const validTypes = ['image/jpeg', 'image/png', 'application/pdf'];
const maxSize = 5 * 1024 * 1024; // 5MB
if (!validTypes.includes(file.type)) {
alert("Geçersiz dosya türü!");
return false;
}
if (file.size > maxSize) {
alert("Dosya boyutu 5MB'ı geçemez!");
return false;
}
return true;
};
Bu fonksiyon, dosya işleme sürecinden hemen önce çağrılmalıdır. Güvenlik için her zaman sunucu tarafında da aynı kontrolleri tekrarlamanız gerektiğini unutmayın.
Kritik Güvenlik Uyarısı: İstemci tarafındaki (Client-side) doğrulamalar sadece kullanıcı deneyimi içindir. Asla sunucu tarafındaki doğrulama yerine geçemez. Yüklenen dosyaları mutlaka sunucuda tekrar tarayın ve dosya uzantılarını değil, içeriklerini (Magic Bytes) kontrol edin.
Görsel Geri Bildirim ve Durum Yönetimi
Kullanıcı bir dosyayı sürüklediğinde, sürükleme alanının aktif olduğunu anlaması gerekir. Bunun için useState kullanarak bir isDragging durumu tutabiliriz. Bu durum, bileşene CSS sınıfları ekleyerek görsel bir değişiklik yapmamızı sağlar.
import { useState } from 'react';
const DragDropArea = () => {
const [isDragging, setIsDragging] = useState(false);
return (
setIsDragging(true)}
onDragLeave={() => setIsDragging(false)}
onDrop={() => setIsDragging(false)}
className={isDragging ? 'active-border' : 'default-border'}
>
{isDragging ? 'Bırakın!' : 'Dosyaları Sürükleyin'}
);
};
CSS tarafında .active-border sınıfına farklı bir arka plan rengi veya kenarlık stili vererek kullanıcıya etkileşimli bir deneyim sunabilirsiniz.
Dosyaları Sunucuya Gönderme Adımları
Dosyalar doğrulandıktan sonra, bunları sunucuya FormData nesnesi aracılığıyla göndermemiz gerekir. Bu yöntem, dosyaları multipart/form-data formatında paketler.
const uploadFiles = async (files) => {
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append('file', files[i]);
}
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
});
if (response.ok) {
alert("Yükleme başarılı!");
}
};
Bu örnekte fetch API kullanılmıştır. Büyük dosya yüklemelerinde axios gibi kütüphanelerle yükleme ilerleme durumunu (progress bar) takip etmek daha kolay olabilir.
Yöntemlerin Karşılaştırılması
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| Yerel HTML5 API | Dış bağımlılık yok, hafif | Daha fazla kod yazımı gerektirir |
| React Dropzone | Hızlı kurulum, zengin özellikler | Proje boyutunu artırır |
Sıkça Sorulan Sorular
Sürükle bırak alanı neden çalışmıyor?
Genellikle onDragOver olayında e.preventDefault() çağrılmadığı için tarayıcı varsayılan davranışı sergiliyordur. Kodunuzu kontrol edin.
Çoklu dosya yüklemeyi nasıl desteklerim?
dataTransfer.files bir FileList nesnesidir. Bunu Array.from(e.dataTransfer.files) ile diziye çevirerek map fonksiyonu ile işleyebilirsiniz.
Mobil cihazlarda sürükle bırak çalışır mı?
Hayır, sürükle-bırak API'si dokunmatik ekranlarda desteklenmez. Mobil cihazlar için mutlaka bir alanı da sunmalısınız.
Dosya yükleme sırasında iptal edebilir miyim?
Evet, AbortController kullanarak devam eden bir fetch isteğini iptal edebilirsiniz.
Yükleme sırasında kullanıcıya ilerleme çubuğu nasıl gösterilir?
XMLHttpRequest kullanarak onprogress olayını dinleyebilir veya axios kütüphanesinin onUploadProgress özelliğini kullanabilirsiniz.
Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanırken mutlaka XSS (Cross-Site Scripting) ve CSRF korumalarını uygulayın. Kullanıcıdan gelen dosyaları asla doğrudan sunucuda çalıştırmayın veya genel dizinlerde saklamayın.
İleri Düzey İpuçları: Dosya Önizleme ve Bellek Yönetimi
Kullanıcı deneyimini bir üst seviyeye taşımak için yüklenen dosyaların sunucuya gitmeden önce tarayıcı üzerinde önizlenmesi oldukça kritiktir. Özellikle görsel dosyalar için URL.createObjectURL() metodunu kullanarak geçici bir referans oluşturabilirsiniz. Ancak, bu yöntemi kullanırken bellek sızıntılarını önlemek için temizlik (cleanup) işlemini ihmal etmemelisiniz.
const [preview, setPreview] = useState(null);
const handleFile = (file) => {
if (file.type.startsWith('image/')) {
const objectUrl = URL.createObjectURL(file);
setPreview(objectUrl);
// Belleği temizlemek için cleanup fonksiyonu
return () => URL.revokeObjectURL(objectUrl);
}
};
Büyük dosyalarda tarayıcının donmasını engellemek için Web Workers yapısını veya Blob parçalama (chunking) yöntemlerini kullanarak dosya okuma işlemlerini ana iş parçacığının (main thread) dışına çıkarmanız önerilir.
Alternatif Yaklaşım: Kütüphane Kullanımı ile Hızlı Geliştirme
Özel bir çözüm geliştirmek yerine, karmaşık gereksinimleri (büyük dosya yükleme, yeniden deneme, chunking) yönetmek için topluluk tarafından desteklenen kütüphaneleri tercih edebilirsiniz. react-dropzone, sektör standardı haline gelmiş, yüksek performanslı ve erişilebilirlik (a11y) odaklı bir çözümdür.
Kütüphane kullanmanın avantajları şunlardır:
- Erişilebilirlik: Klavye ile dosya seçimi ve ekran okuyucu desteği hazır gelir.
- Esneklik: Dosya tipi kısıtlamaları ve boyut kontrolleri için yerleşik konfigürasyonlar sunar.
- Hata Yönetimi: Sürükleme sırasında oluşan hataları (geçersiz dosya tipi vb.) yönetmek için hazır callback yapıları sağlar.
import { useDropzone } from 'react-dropzone';
function MyDropzone() {
const { getRootProps, getInputProps } = useDropzone({
accept: {'image/*': []},
onDrop: acceptedFiles => {
console.log(acceptedFiles);
}
});
return (
Dosyaları buraya sürükleyin veya tıklayın.
);
}
Performans ve Ölçeklenebilirlik Testleri
Dosya yükleme alanınızın üretim ortamında nasıl davrandığını anlamak için şu test senaryolarını uygulamanız önemlidir:
- Yavaş Ağ Simülasyonu: Tarayıcı geliştirici araçlarındaki "Network" sekmesinden "Slow 3G" modunu seçerek yükleme çubuğunun (progress bar) kararlılığını test edin.
- Dosya Boyutu Sınırı: Sunucunun kabul edeceği maksimum boyuttan daha büyük bir dosyayı yüklemeye çalışarak istemci tarafındaki hata mesajının tetiklendiğinden emin olun.
- Eşzamanlı Yükleme: Aynı anda 10+ dosya sürükleyerek uygulamanın durum yönetiminin (state management) bu yükü nasıl karşıladığını gözlemleyin.
İpucu: Eğer uygulamanız çok yüksek trafik alıyorsa, dosyaları doğrudan sunucunuza değil, AWS S3 veya Cloudinary gibi bulut depolama servislerine Pre-signed URL kullanarak yüklemek, sunucu kaynaklarınızı ciddi oranda rahatlatacaktır.
Sonuç
React ile sürükle-bırak dosya yükleme alanı oluşturmak, uygulamanızın profesyonellik seviyesini artıran temel bir yetenektir. HTML5'in yerel API'lerini kullanarak bu süreci yönetmek, uygulamanızın performanslı ve hafif kalmasını sağlar. Öğrendiğiniz bu adımları, dosya önizleme (preview) ve yükleme ilerleme durumu (progress bar) gibi özelliklerle genişleterek kullanıcı deneyimini mükemmelleştirebilirsiniz. Bir sonraki adım olarak, dosya yükleme işlemlerini yönetmek için bir useFileUpload özel hook'u (custom hook) yazmayı deneyebilirsiniz.
Yorumlar (0)
Yorum Yaz