React İle Özel Kanca Kullanarak Sayfa İçi Kaydırma Efekti Nasıl Yapılır?

React İle Özel Kanca Kullanarak Sayfa İçi Kaydırma Efekti Nasıl Yapılır?
React İle Özel Kanca Kullanarak Sayfa İçi Kaydırma Efekti Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Bu projeyi uygulamak için bilgisayarınızda Node.js yüklü olmalı ve bir React projesi oluşturmuş olmalısınız. 2026 itibarıyla Vite kullanmanızı öneriyoruz. Projenizi oluşturmak için terminalinizde şu komutu çalıştırabilirsiniz:

npm create vite@latest scroll-app -- --template react
cd scroll-app
npm install

Bu komutlar, modern bir geliştirme ortamı kurmanızı sağlar. React 19 ve üzeri sürümlerle uyumlu bir yapı üzerinden ilerleyeceğiz. Projenin dizin yapısında src/hooks adında bir klasör oluşturmanız, düzenli bir çalışma için ilk adım olacaktır.

Özel Kanca (Custom Hook) Mantığı Nedir?

Özel kancalar, React'in yerleşik kancalarını (useState, useEffect vb.) kullanarak kendi mantığınızı oluşturmanıza olanak tanır. Sayfa içi kaydırma için bir kanca oluşturmanın temel amacı, kaydırma işlemini tetikleyen fonksiyonu ve hedef referansı tek bir noktadan yönetmektir.

Aşağıdaki kod bloğu, temel bir useScrollTo kancasının iskeletini oluşturur:

import { useRef } from 'react';

export const useScrollTo = () => {
  const elementRef = useRef(null);

  const scrollToElement = () => {
    if (elementRef.current) {
      elementRef.current.scrollIntoView({ behavior: 'smooth' });
    }
  };

  return { elementRef, scrollToElement };
};

Bu kanca, bir ref nesnesi döndürür ve bu nesneyi hedeflediğiniz DOM elemanına bağlamanızı sağlar. scrollIntoView metodu, modern tarayıcıların sunduğu yerel bir API'dir.

Adım Adım Özel Kanca Uygulaması

Şimdi bu kancayı gerçek bir bileşen içinde nasıl kullanacağımızı inceleyelim. İlk olarak, kancamızı daha esnek hale getirelim. Sadece kaydırma yapmakla kalmayıp, kaydırma sonrası bir işlem tetiklemek isteyebiliriz.

import { useRef } from 'react';

export const useSmoothScroll = (offset = 0) => {
  const targetRef = useRef(null);

  const executeScroll = () => {
    if (targetRef.current) {
      const top = targetRef.current.getBoundingClientRect().top + window.scrollY - offset;
      window.scrollTo({ top, behavior: 'smooth' });
    }
  };

  return [targetRef, executeScroll];
};

Bu versiyonda, offset parametresi ekleyerek sabit başlık (header) gibi unsurların kaydırmayı engellemesini önlüyoruz. getBoundingClientRect sayesinde elemanın konumunu tam olarak hesaplıyoruz.

Bileşen İçinde Kullanım Örneği

Oluşturduğumuz kancayı bir "Hakkımızda" bölümünde kullanalım. Aşağıdaki örnek, bir buton tıklandığında ilgili bölüme akıcı bir şekilde nasıl gidileceğini gösterir:

import { useSmoothScroll } from './hooks/useSmoothScroll';

function App() {
  const [aboutRef, scrollToAbout] = useSmoothScroll(80);

  return (
    
Hakkımızda Bölümüne Git

Hakkımızda

Burada şirket bilgilerimiz yer almaktadır.

); }

Burada aboutRef değişkenini hedef bölüme bağladık. Butona tıklandığında scrollToAbout fonksiyonu çalışarak sayfayı ilgili bölüme kaydırır.

Yöntem Karşılaştırması

Yöntem Avantaj Dezavantaj
Anchor (a href) Basit, SEO dostu Özelleştirme zor, kaba geçiş
Özel Kanca Tam kontrol, modüler Ekstra kod yükü
Kütüphane (framer-motion) Gelişmiş animasyon Yüksek paket boyutu

Kritik Uyarılar ve Güvenlik

Dikkat: Sayfa içi kaydırma işlemlerinde ref nesnelerinin null olma ihtimalini her zaman kontrol edin. Ayrıca, çok büyük sayfalar üzerinde sürekli kaydırma tetiklemek performans sorunlarına yol açabilir. Kullanıcı etkileşimlerini kısıtlamadan, gereksiz yeniden render (re-render) işlemlerinden kaçının.

Güvenlik açısından, kullanıcı tarafından sağlanan verileri (örneğin URL parametreleri ile kaydırma) doğrudan DOM'a yansıtırken XSS (Cross-Site Scripting) saldırılarına karşı dikkatli olun. DOM elemanlarına doğrudan erişim sağladığınız için, kullanıcı girdilerini sanitize etmeden ref ile etkileşime sokmayın.

Hata Ayıklama (Debugging) İpuçları

Eğer kaydırma çalışmıyorsa, şu adımları izleyin:

  • ref nesnesinin doğru bileşene atandığından emin olun.
  • CSS tarafında scroll-behavior: smooth özelliğinin çakışıp çakışmadığını kontrol edin.
  • Tarayıcı konsolunda targetRef.current değerinin null olup olmadığını console.log ile kontrol edin.

Sıkça Sorulan Sorular

Özel kanca kullanmak neden a etiketinden daha iyidir?

Özel kancalar, kaydırma mantığını JavaScript ile kontrol etmenize olanak tanır. Bu sayede kaydırma bittiğinde bir fonksiyon çalıştırmak veya kaydırma hızını dinamik olarak değiştirmek gibi karmaşık işlemleri kolayca yapabilirsiniz.

Mobil cihazlarda kaydırma performansı nasıl artırılır?

Mobil cihazlarda scrollIntoView metodu genellikle iyi çalışır. Ancak karmaşık animasyonlar eklemek isterseniz, requestAnimationFrame kullanarak kaydırma işlemini optimize edebilirsiniz.

Birden fazla bölüm için tek kanca yeterli mi?

Evet, oluşturduğumuz useSmoothScroll kancasını her bölüm için ayrı bir örnek (instance) olarak çağırarak kullanabilirsiniz.

Sayfa yüklendiğinde belirli bir bölüme otomatik kaydırma yapabilir miyim?

Evet, useEffect kullanarak bileşen yüklendiğinde (mount) executeScroll fonksiyonunu çağırarak otomatik kaydırma sağlayabilirsiniz.

Bu kanca SSR (Server Side Rendering) ile çalışır mı?

Evet, ancak window nesnesine erişmeye çalıştığınız için kanca içindeki işlemleri useEffect içerisinde veya typeof window !== 'undefined' kontrolü ile yapmalısınız.

İleri Seviye Optimizasyon: Kaydırma Animasyonlarını Özelleştirme

Oluşturduğumuz temel useScrollTo kancası, tarayıcının yerleşik scrollIntoView metodunu kullanır. Ancak, kullanıcı deneyimini bir üst seviyeye taşımak için kaydırma hızını, ivmelenmesini (easing) ve ofset değerlerini manuel olarak kontrol etmek isteyebilirsiniz. Özellikle sabit (fixed) header yapısına sahip sitelerde, kaydırma işleminin header'ın altında kalmaması için bir "offset" değeri eklemek kritik bir gereksinimdir.

Aşağıdaki geliştirilmiş yapı, kaydırma işlemini window.scrollTo kullanarak daha hassas bir şekilde yönetmenizi sağlar:

const useSmoothScroll = (offset = 0) => {
  const scrollToElement = (elementId) => {
    const element = document.getElementById(elementId);
    if (element) {
      const elementPosition = element.getBoundingClientRect().top;
      const offsetPosition = elementPosition + window.pageYOffset - offset;

      window.scrollTo({
        top: offsetPosition,
        behavior: "smooth"
      });
    }
  };
  return scrollToElement;
};

Performans İzleme ve Intersection Observer Entegrasyonu

Sayfa içi kaydırma işlemlerinde performans, özellikle karmaşık DOM yapılarında düşebilir. scroll event'ini sürekli dinlemek yerine, IntersectionObserver API'sini kullanarak bileşenlerin görünürlüğünü takip etmek çok daha verimlidir. Bu yöntem, ana iş parçacığını (main thread) yormadan kaydırma pozisyonlarını yönetmenize olanak tanır.

Aşağıdaki örnek, bir bölümün ekrana girip girmediğini kontrol eden ve buna göre tetiklenen bir yapıyı gösterir:

import { useEffect, useState } from 'react';

const useOnScreen = (ref) => {
  const [isIntersecting, setIntersecting] = useState(false);

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      setIntersecting(entry.isIntersecting);
    });

    if (ref.current) {
      observer.observe(ref.current);
    }
    return () => {
      observer.disconnect();
    };
  }, [ref]);

  return isIntersecting;
};

Entegrasyon İpuçları

  • Debounce Kullanımı: Eğer kaydırma sırasında bir event tetikliyorsanız, fonksiyonun çok sık çalışmaması için lodash.debounce gibi kütüphanelerle tetikleyiciyi sınırlandırın.
  • GPU Hızlandırma: Kaydırma animasyonları sırasında will-change: transform CSS özelliğini kullanarak tarayıcının donanım hızlandırmasından faydalanabilirsiniz.
  • Erişilebilirlik (A11y): Kaydırma işlemi tamamlandığında, odaklanılan elemente tabIndex="-1" vererek ve element.focus() metodunu çağırarak klavye kullanıcılarının deneyimini iyileştirmeyi unutmayın.
Not: Sayfa içi kaydırma yaparken URL'deki hash (#) değerini güncellemek, kullanıcının "Geri" butonuna bastığında doğru yere dönmesini sağlar. Bunu yapmak için window.history.pushState(null, null, '#element-id') komutunu kullanabilirsiniz.

Sonuç

React ile özel kanca kullanarak sayfa içi kaydırma yapmak, hem kodunuzun okunabilirliğini artırır hem de projenize profesyonel bir dokunuş katar. Bu rehberde öğrendiğiniz modüler yapı sayesinde, artık kendi kaydırma mantığınızı projenin her yerinde kolayca kullanabilirsiniz. Bir sonraki adım olarak, kaydırma esnasında aktif menü öğesini vurgulayan bir "ScrollSpy" kancası geliştirmeyi deneyebilirsiniz.

Kod güvenliği sorumluluk reddi: Bu rehberde paylaşılan kodlar eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce gerekli testleri yapmalı ve projenizin güvenlik politikalarına uygunluğunu denetlemelisiniz.

Bu yazıya tepkinizi paylaşın:
Deniz Arslan

On yıldır pratik ev çözümleri ve hayat kolaylaştıran teknikler üzerine içerik üretiyorum. Okuyucuların karmaşık süreçleri en basit adımlarla çözmelerine yardımcı oluyorum.

Yorumlar (0)

Yorum Yaz