React'te Bağımlı Filtreler: Bir Filtreyi Seçince Diğerinin Güncellenmesi
Ana Grup seçildiğinde Alt Grup listesinin otomatik güncellenmesi nasıl yapılır? React ile cascading (bağımlı) filtre pattern'ini adım adım uygulayın.
Sorun: Filtreler Birbiriyle Uyumsuz
Stok tablosunda 3 filtre var: Ana Grup, Alt Grup ve Depo. Kullanıcı “Seramik” ana grubunu seçiyor — ama Alt Grup menüsünde hâlâ boya, kablo, vida gibi alakasız seçenekler görünüyor.
Ana Grup: [Seramik ▼] ← Seçildi
Alt Grup: [Tümü ▼]
├── Boya ← Seramikle ne alakası var?
├── Kablo ← İlgisiz
├── Yer Seramiği ← ✅ Bu olmalı
└── Duvar Fayansı← ✅ Bu olmalı
Kullanıcı yanlış seçim yapıyor, sonuç bulamıyor, “sistem çalışmıyor” diyor.
Bağımlı filtre demek: Birinci filtreyi seçince, ikinci filtredeki seçenekler otomatik olarak ayıklansın.
Basit Mantık
1. Kullanıcı "Seramik" seçti
2. → Alt Grup listesi güncellenir: sadece Yer Seramiği, Duvar Fayansı, Mozaik
3. → Tablo da güncellenir: sadece seramik ürünleri gösterir
Adım 1: Filtre Durumunu Tutma
En önemli kısım: Ana Grup değişince Alt Grup sıfırlanmalı. Yoksa kullanıcı “Seramik → Boya” gibi imkansız bir kombinasyonda kalır.
function useFiltreler() {
const [anaGrup, setAnaGrup] = useState('');
const [altGrup, setAltGrup] = useState('');
// Ana Grup değişince Alt Grup sıfırla
const anaGrupDegistir = (yeniDeger) => {
setAnaGrup(yeniDeger);
setAltGrup(''); // ← Kritik: sıfırla
};
return {
anaGrup, altGrup,
anaGrupDegistir,
setAltGrup,
};
}
Adım 2: Alt Grup Seçeneklerini Ana Gruba Göre Çekme
Ana Grup seçildiğinde veritabanından sadece o grubun alt gruplarını getiriyoruz:
function useAltGrupSecenekleri(anaGrup) {
return useQuery({
queryKey: ['alt-gruplar', anaGrup], // anaGrup değişince yeniden çeker
queryFn: async () => {
let sorgu = supabase
.from('v3_stock')
.select('alt_grup');
// Ana Grup seçildiyse, sadece ona ait olanları getir
if (anaGrup) {
sorgu = sorgu.eq('ana_grup', anaGrup);
}
const { data } = await sorgu;
// Tekrarsız liste oluştur
return [...new Set(data?.map(d => d.alt_grup))];
},
});
}
Buradaki sihir: queryKey içinde anaGrup var. React Query, ana grup her değiştiğinde otomatik olarak yeni alt grup listesini çeker.
Adım 3: Ekrana Koyma
function FiltreBar() {
const { anaGrup, altGrup, anaGrupDegistir, setAltGrup } = useFiltreler();
const { data: anaGruplar } = useAnaGrupSecenekleri();
const { data: altGruplar } = useAltGrupSecenekleri(anaGrup);
return (
<div className="filtre-bar">
<select value={anaGrup} onChange={e => anaGrupDegistir(e.target.value)}>
<option value="">Tüm Ana Gruplar</option>
{anaGruplar?.map(g => <option key={g} value={g}>{g}</option>)}
</select>
<select value={altGrup} onChange={e => setAltGrup(e.target.value)}>
<option value="">Tüm Alt Gruplar</option>
{altGruplar?.map(g => <option key={g} value={g}>{g}</option>)}
</select>
</div>
);
}
Kullanıcı Ne Yaşar?
1. Sayfa açıldı
Ana Grup: [Tümü] Alt Grup: [Tümü] → 15.000 ürün
2. "Seramik" seçildi
Ana Grup: [Seramik] Alt Grup: [Tümü] → 2.300 ürün
Seçenekler: Yer Seramiği, Duvar Fayansı, Mozaik
3. "Yer Seramiği" seçildi
Ana Grup: [Seramik] Alt Grup: [Yer Ser.] → 450 ürün
4. Ana Grup değiştirildi: "Boya"
Ana Grup: [Boya] Alt Grup: [Tümü] → Alt Grup sıfırlandı!
Seçenekler: İç Cephe, Dış Cephe, Astar
Kullanıcı asla uyumsuz bir kombinasyon seçemez.
Aramayı Optimize Etme: Her Tuşa Basmada Sorgu Atma
Arama kutusuna yazarken her harf için veritabanına gitmek istemezsiniz. “Debounce” ile kullanıcı yazmayı bıraktıktan sonra sorgu atılır:
function useDebounce(deger, gecikme = 300) {
const [gecikmeli, setGecikmeli] = useState(deger);
useEffect(() => {
const zamanlayici = setTimeout(() => setGecikmeli(deger), gecikme);
return () => clearTimeout(zamanlayici);
}, [deger, gecikme]);
return gecikmeli;
}
// Kullanım:
const aramaMetni = useDebounce(filters.search, 300);
// → Kullanıcı yazmayı bıraktıktan 300ms sonra sorgu atar
Bu Yapıyla 2-3 Filtre Rahatça Çalışır
Ama 5+ bağımlı filtre zinciri (Ana Grup → Alt Grup → Marka → Renk → Boyut) olunca, 15.000+ üründe performans ve UX konularında daha ileri teknikler gerekir.
Biz böyle bir yapıyı production’da çalıştırıyoruz. İhtiyacınız olursa deneyimimizden faydalanabilirsiniz.
Bu yazı AstaFlow Case Study serisinin bir parçasıdır.