React'te Sonsuz Kaydırma (Infinite Scroll) Nasıl Uygulanır?
🎯 Bu Rehberde Ne Öğreneceksiniz?
Bu rehberde, React uygulamalarınızda Sonsuz Kaydırma (Infinite Scroll) özelliğini adım adım uygulayacaksınız.
Bu özellik, kullanıcı sayfanın sonuna ulaştığında otomatik olarak yeni içerik yüklenmesini sağlar.
Ayrıca, kaydırma performansını artırmak için lodash.debounce ile olay optimizasyonu yapmayı öğreneceksiniz.
Örnek olarak, NASA'nın Astronomy Picture of the Day (APOD) API’sini kullanacağız.
🧠 Teknik Özet
| Kriter | Açıklama |
|---|---|
| Ana Teknik Konu | React uygulamasında Sonsuz Kaydırma (Infinite Scroll) mekanizması |
| Hangi Problemi Çözüyor? | Sayfalandırma (pagination) yerine kesintisiz içerik akışı sağlar. Sosyal medya benzeri akışlar için idealdir. |
| Kullanıcı Adımları | 1️⃣ Proje kurulumu 2️⃣ Kaydırma olayını yakalama 3️⃣ Debounce optimizasyonu 4️⃣ API verisi çekme 5️⃣ Başlangıç yüklemesi ve hata yönetimi |
| Teknik Amaç | Scroll hareketini dinleyerek, sayfa altına inildiğinde otomatik veri yüklemek |
⚙️ 1. Proje Kurulumu ve Gerekli Paketlerin Yüklenmesi
Sonsuz kaydırma özelliğini geliştirmek için temel React projesini oluşturun.
Veri çekmek için superagent, performans optimizasyonu için lodash.debounce kullanacağız.
npx create-react-app rabisu-sonsuz-kaydirma
cd rabisu-sonsuz-kaydirma
npm install [email protected] [email protected]
💡 superagent, API istekleri yapmak için; lodash.debounce, scroll olaylarını optimize etmek için kullanılır.
🧩 2. InfiniteSpace Bileşenini Tanımlama
src/InfiniteSpace.js dosyasını oluşturun ve gerekli import’ları ekleyin.
import React, { Component } from 'react';
import request from 'superagent';
import debounce from 'lodash.debounce';
class InfiniteSpace extends Component {
constructor(props) {
super(props);
this.state = {
apods: [],
};
// Kaydırma olayını 100ms gecikmeyle debounce ediyoruz.
window.onscroll = debounce(() => {
const { loadApods } = this;
// Sayfa sonuna ulaşıldıysa yeni veriyi yükle.
if (window.innerHeight + document.documentElement.scrollTop === document.documentElement.offsetHeight) {
loadApods();
}
}, 100);
}
render() {
return (
<div style={{ padding: 10 }}>
<h1>Sonsuz Uzay!</h1>
<p>Daha fazla içerik için aşağı kaydırın!</p>
</div>
);
}
}
export default InfiniteSpace;
💬 Bu yapı, scroll olayını dinler ve sayfa altına inildiğinde loadApods() fonksiyonunu çağırır.
🌠 3. API'den Veri Çekme ve Tarih Hesaplama
a. Tarih Ofseti Hesaplama (dayOffset)
NASA API’si tek bir güne ait veri döndürür. Önceki günlerin içeriklerini almak için ofset hesaplayalım.
dayOffset = () => {
let today = new Date();
let day = today.setDate(today.getDate() - this.state.apods.length);
return new Date(day).toISOString().split('T')[0];
};
📅 Bu fonksiyon, yüklenen veri sayısına göre geçmiş tarihleri hesaplar.
b. Veri Yükleme Metodu (loadApods)
superagent ile API’ye istek atıp gelen veriyi apods dizisine ekleyelim.
loadApods = () => {
this.setState({ isLoading: true }, () => {
request
.get('https://api.nasa.gov/planetary/apod?date=' + this.dayOffset() + '&api_key=DEMO_KEY')
.then((results) => {
const nextApod = {
date: results.body.date,
title: results.body.title,
explanation: results.body.explanation,
copyright: results.body.copyright,
media_type: results.body.media_type,
url: results.body.url,
};
this.setState(prevState => ({
hasMore: prevState.apods.length < 5,
isLoading: false,
apods: [...prevState.apods, nextApod],
}));
})
.catch((err) => {
this.setState({ error: err.message, isLoading: false });
});
});
};
🚀 Bu fonksiyon, her kaydırmada yeni bir günün verisini çeker ve listeye ekler.
🪐 4. Başlangıç Yüklemesi ve Durum Yönetimi
Bileşen yüklendiğinde ilk veriyi çekelim. Ayrıca error, isLoading ve hasMore durumlarını yönetelim.
componentDidMount() {
this.loadApods();
}
this.state = {
error: false,
hasMore: true,
isLoading: false,
apods: [],
};
// Scroll sırasında duruma göre işlem yap
window.onscroll = debounce(() => {
const { loadApods, state: { error, isLoading, hasMore } } = this;
if (error || isLoading || !hasMore) return;
if (window.innerHeight + document.documentElement.scrollTop === document.documentElement.offsetHeight) {
loadApods();
}
}, 100);
⚙️ isLoading tekrar eden istekleri engeller, error hataları yakalar, hasMore ise içerik sınırını belirler.
🌌 5. Verilerin Render Edilmesi
API’den gelen verileri ekranda listeleyelim.
render() {
const { error, hasMore, isLoading, apods } = this.state;
return (
<div style={{ padding: 10 }}>
<h1>Sonsuz Uzay Galerisi</h1>
<p>Daha fazla içerik için aşağı kaydırın!</p>
{apods.map(apod => (
<React.Fragment key={apod.date}>
<hr />
<div>
<h2>{apod.title}</h2>
{apod.media_type === 'image' &&
<img src={apod.url} alt={apod.title} style={{ maxWidth: '100%', height: 'auto' }} />
}
{apod.media_type === 'video' &&
<iframe src={apod.url} width='640' height='360' style={{ maxWidth: '100%' }}></iframe>
}
<p>{apod.explanation}</p>
<small>Telif Hakkı: {apod.copyright}</small>
</div>
</React.Fragment>
))}
<hr />
{error && <div style={{ color: '#900' }}>Hata: {error}</div>}
{isLoading && <div>Yeni içerikler yükleniyor...</div>}
{!hasMore && <div>Tüm içerik yüklendi.</div>}
</div>
);
}
💡 Görseller ve videolar dinamik olarak render edilir, kullanıcıya durum bilgisi gösterilir.
🚀 6. App.js Dosyasına Dahil Etme
import React from 'react';
import InfiniteSpace from './InfiniteSpace';
function App() {
return (
<div className="App">
<InfiniteSpace />
</div>
);
}
export default App;
🔭 Şimdi npm start komutunu çalıştırın. Tarayıcıda sayfayı aşağı kaydırdıkça yeni NASA içeriklerinin otomatik yüklendiğini göreceksiniz.
💬 Sıkça Sorulan Sorular (SSS)
- Sonsuz kaydırma performans sorununa yol açar mı?
Evet, doğru uygulanmazsa tarayıcı belleği şişebilir. debounce kullanımı olay sıklığını azaltarak performansı korur.
- debounce yerine throttle kullanılabilir mi?
Evet. debounce, olaylar durana kadar bekler; throttle ise belirli aralıklarla çalışır. Sonsuz kaydırmada debounce genelde daha uygundur.
- hasMore ne işe yarar?
Yeni veri kalmadığında hasMore = false olur ve istekler durur. Bu, API limitlerini korur ve gereksiz yüklemeleri engeller.
- Intersection Observer API kullanılabilir mi?
Kesinlikle evet. Modern bir yöntemdir ve scroll yerine gözlemlenecek bir hedef eleman belirlenir. Mobil performansı artırır ve önerilen yaklaşımdır.
- Başlangıçta neden componentDidMount kullanıyoruz?
Sayfa ilk yüklendiğinde en az bir içerik gösterilmesi gerekir. Bu metod, ilk API çağrısını otomatik yapar.
🏁 Sonuç
Bu rehberde, React’te Sonsuz Kaydırma (Infinite Scroll) özelliğini uygulamayı öğrendiniz. Scroll algılama, debounce optimizasyonu ve hata yönetimiyle kullanıcıya kesintisiz içerik akışı sağladınız.
💡 Şimdi bu özelliği Rabisu Bulut üzerindeki React projelerinizde deneyin ve kullanıcılarınıza akıcı bir deneyim sunun!
yaml