Gereksinimler ve Ön Hazırlık
Sonsuz kaydırma yapısını kurmak için modern bir React ortamına ihtiyacınız vardır. 2026 standartlarında Vite veya Next.js gibi güncel araçlar kullanmanızı öneririm. Projenizde react ve react-dom paketlerinin 18.x veya üzeri bir sürümde olduğundan emin olun.
- Node.js (LTS sürümü)
- Temel React Hooks bilgisi (useState, useEffect, useRef)
- Intersection Observer API'ye dair temel kavramlar
Intersection Observer, bir öğenin (target) başka bir öğe veya viewport (görüntü alanı) ile kesişimini asenkron olarak izlememizi sağlar. Bu, kaydırma olaylarını her pikselde takip etmek yerine, sadece belirli bir nokta geçildiğinde tetiklendiği için CPU kullanımını minimize eder.
Intersection Observer Hook Yapısı
Sonsuz kaydırma mantığını tekrar kullanılabilir bir yapıya dönüştürmek için özel bir hook (custom hook) oluşturmak en temiz yaklaşımdır. Bu hook, bir referans öğesini izleyecek ve o öğe ekrana girdiğinde bir callback fonksiyonunu tetikleyecektir.
import { useEffect, useRef } from 'react';
export const useIntersectionObserver = (callback, options) => {
const targetRef = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
const [entry] = entries;
if (entry.isIntersecting) {
callback();
}
}, options);
const currentTarget = targetRef.current;
if (currentTarget) observer.observe(currentTarget);
return () => {
if (currentTarget) observer.unobserve(currentTarget);
};
}, [callback, options]);
return targetRef;
};
Bu kodda, IntersectionObserver nesnesini oluşturuyor ve targetRef ile bağladığımız elementin isIntersecting durumunu kontrol ediyoruz. useEffect temizleme fonksiyonu (cleanup function) sayesinde, bileşen kaldırıldığında gözlemciyi durdurarak bellek sızıntılarını engelliyoruz.
Veri Çekme ve Durum Yönetimi
Sonsuz kaydırma için verileri sayfa sayfa (pagination) çekmek gerekir. API'nizin sayfa numarası veya offset parametrelerini desteklediğini varsayıyoruz. Aşağıdaki örnekte, verileri yönetmek için useState kullanıyoruz.
import { useState, useEffect } from 'react';
const useFetchData = (page) => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
const response = await fetch(`https://api.ornek.com/veriler?page=${page}`);
const result = await response.json();
setData((prev) => [...prev, ...result]);
setLoading(false);
};
fetchData();
}, [page]);
return { data, loading };
};
Burada verileri prev değerine ekleyerek (spread operator kullanarak) mevcut listeyi koruyoruz. loading durumu, kullanıcıya verilerin yüklendiğini bildirmek için kritik öneme sahiptir.
Sonsuz Kaydırma Bileşenini Birleştirme
Şimdi hooklarımızı ana bileşenimizde birleştirelim. Liste sonuna bir "gözlemci" div'i ekleyerek, bu div ekrana girdiğinde bir sonraki sayfayı tetikleyeceğiz.
import React, { useState } from 'react';
const InfiniteList = () => {
const [page, setPage] = useState(1);
const { data, loading } = useFetchData(page);
const observerRef = useIntersectionObserver(() => setPage((p) => p + 1), {
threshold: 1.0,
});
return (
{data.map((item) => (
{item.title}
))}
{loading && Yükleniyor...
}
);
};
threshold: 1.0 değeri, elementin tamamen görünür olması durumunda tetikleme yapacağı anlamına gelir. Bu, kullanıcı listenin en altına ulaştığında yeni verilerin yüklenmesini sağlar.
Performans ve Güvenlik Karşılaştırması
Sonsuz kaydırma yöntemlerini ve teknik yaklaşımları aşağıdaki tabloda inceleyebilirsiniz.
| Yöntem | Performans | Uygulama Zorluğu |
|---|---|---|
| Scroll Event | Düşük (CPU yoğun) | Kolay |
| Intersection Observer | Yüksek (Optimize) | Orta |
| Windowing (Virtual List) | Çok Yüksek | Zor |
Kritik Güvenlik Uyarısı: API'den gelen verileri doğrudan
dangerouslySetInnerHTMLile render etmeyin. Bu, XSS (Cross-Site Scripting) saldırılarına kapı aralar. Ayrıca, API isteklerinde CORS politikalarına dikkat edin ve hassas verileri istemci tarafında tutmayın.
Yaygın Hatalar ve Debug İpuçları
Sonsuz kaydırma geliştirirken en sık karşılaşılan sorun, verilerin sürekli tetiklenmesi veya hiç tetiklenmemesidir. Eğer veriler sürekli yükleniyorsa, threshold değerini veya gözlemci div'inin yüksekliğini kontrol edin. Eğer hiç tetiklenmiyorsa, observerRef'in doğru elemente bağlandığından emin olun.
Bir diğer yaygın hata, API'nin tüm verileri gönderdiğinde bile isteğin devam etmesidir. API'nizden gelen yanıtta "hasMore" veya "totalPages" gibi bir alan olup olmadığını kontrol ederek, veriler bittiğinde gözlemciyi durduracak bir mantık eklemelisiniz.
Sıkça Sorulan Sorular
Intersection Observer tüm tarayıcılarda çalışır mı?
Modern tarayıcıların tamamında desteklenmektedir. Eski tarayıcılar için "polyfill" kütüphanelerini projenize dahil edebilirsiniz.
Sonsuz kaydırma SEO'yu etkiler mi?
Evet, arama motorları kaydırma ile yüklenen içeriği her zaman göremeyebilir. Bu nedenle, kritik içerikler için standart pagination (sayfalama) daha güvenlidir.
Gözlemci div'i neden boş bırakıyoruz?
Gözlemci div'i sadece bir işaretçidir. Kullanıcıya görünmesi gerekmez, sadece listenin bittiğini belirtmek için bir referans noktasıdır.
Bellek sızıntılarını nasıl önlerim?
useEffect içindeki cleanup fonksiyonunda observer.unobserve metodunu mutlaka çağırarak, bileşen yok olduğunda gözlemcinin serbest kalmasını sağlayın.
Aynı anda birden fazla istek gitmesini nasıl engellerim?
loading durumunu kontrol ederek, eğer zaten bir istek devam ediyorsa yeni bir istek başlatılmasını engelleyen bir "guard clause" (koruma bloğu) ekleyebilirsiniz.
İleri Düzey Optimizasyon: "Skeleton Screen" Entegrasyonu
Sonsuz kaydırma deneyiminde kullanıcıların en çok şikayet ettiği konu, yeni veriler yüklenirken ekranın boş kalması veya aniden içeriklerin "zıplamasıdır" (Layout Shift). Bunu engellemek için Intersection Observer tetiklendiği anda bir Skeleton Screen (iskelet ekran) bileşeni göstermek, algılanan performansı ciddi oranda artırır.
Aşağıdaki örnekte, veri çekme işlemi devam ederken kullanıcıya bir yüklenme iskeleti sunan yapıyı görebilirsiniz:
const InfiniteList = () => {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(false);
return (
{items.map(item => )}
{loading && (
)}
);
};
Test Senaryoları ve Birim Testi Stratejileri
Sonsuz kaydırma mekanizmasını test ederken en büyük zorluk, tarayıcı API'si olan IntersectionObserver'ın JSDOM ortamında (Jest gibi) varsayılan olarak bulunmamasıdır. Bu durumu aşmak için test ortamında bir Mock oluşturmanız gerekir.
Intersection Observer Mock Kullanımı
Testlerinizde gözlemcinin tetiklenmesini simüle etmek için aşağıdaki kurulumu test dosyanızın başına ekleyebilirsiniz:
// jest.setup.js
global.IntersectionObserver = class IntersectionObserver {
constructor(callback) {
this.callback = callback;
}
observe() { return null; }
unobserve() { return null; }
disconnect() { return null; }
};
// Test içerisinde tetikleme simülasyonu
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
// Veri çekme fonksiyonunu çağır
}
});
Bu strateji ile uygulamanızın kaydırma eşiğine ulaştığında gerçekten veri isteyip istemediğini, loading durumunun doğru değişip değişmediğini ve hata durumunda uygulamanın çöküp çökmediğini kolayca doğrulayabilirsiniz.
Deployment Öncesi Kontrol Listesi
Uygulamanızı canlıya almadan önce şu teknik detayları gözden geçirdiğinizden emin olun:
- API Rate Limiting: Kullanıcı çok hızlı kaydırma yaparsa, sunucunuza saniyede onlarca istek gidebilir. İstekleri kısıtlamak için
debounceveyathrottlemekanizmalarını veri çekme fonksiyonunuza entegre edin. - Error Boundary: Veri çekme sırasında oluşabilecek 404 veya 500 hataları için bir
ErrorBoundarybileşeni kullanarak uygulamanın beyaz ekrana düşmesini engelleyin. - Scroll Restoration: Kullanıcı sayfayı yenilediğinde veya geri döndüğünde, tarayıcının otomatik kaydırma pozisyonunu koruması için
history.scrollRestoration = 'auto'ayarını kontrol edin.
Sonuç
React ile Intersection Observer kullanarak sonsuz kaydırma yapmak, hem kullanıcı deneyimini optimize eder hem de uygulamanızın modern standartlara uygun olmasını sağlar. Bu rehberde öğrendiğiniz custom hook yapısını, projelerinizde farklı listeleme ihtiyaçları için de kolayca uyarlayabilirsiniz. Bir sonraki adım olarak, "Virtual List" (Sanal Liste) kütüphanelerini inceleyerek binlerce verinin olduğu listelerde DOM elemanlarını nasıl daha verimli yöneteceğinizi keşfedebilirsiniz.
Yasal Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce hata yönetimi, veri doğrulama ve güvenlik testlerini (OWASP standartlarına göre) tamamlamanız önerilir.


Yorumlar (0)
Yorum Yaz