Skip to main content

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

KriterAçıklama
Ana Teknik KonuReact 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)

  1. 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.

  1. 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.

  1. hasMore ne işe yarar?

Yeni veri kalmadığında hasMore = false olur ve istekler durur. Bu, API limitlerini korur ve gereksiz yüklemeleri engeller.

  1. 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.

  1. 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