React İle Web Uygulamalarında Yazı Yazdırma Efekti Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Bu uygulamayı geliştirmek için bilgisayarınızda Node.js'in güncel LTS sürümünün yüklü olması gerekmektedir. Projenizi oluştururken Vite gibi hızlı yapılandırma araçlarını tercih etmeniz önerilir. Çalışma ortamınızda React 18 veya üzeri bir sürümün yüklü olduğundan emin olun.

  • Node.js (v20 veya üzeri)
  • React (v18+)
  • Temel JavaScript (ES6+ sözdizimi)
  • CSS (Stil yönetimi için)

Projenizi başlatmak için terminalde npm create vite@latest komutunu kullanabilir ve React + TypeScript veya JavaScript şablonunu seçebilirsiniz. Kurulum tamamlandıktan sonra npm install komutu ile gerekli paketleri yükleyerek geliştirmeye hazır hale gelebilirsiniz.

Adım 1: Yazı Yazdırma Efekti İçin Temel Mantık Kurulumu

Yazı yazdırma efekti, aslında bir dizinin veya metin bloğunun karakter karakter, belirli bir zaman aralığıyla (set interval) state içerisine eklenmesi işlemidir. Bu işlemde useState ve useEffect kancalarını kullanacağız.

import { useState, useEffect } from 'react';

const Typewriter = ({ text, speed = 100 }) => {
  const [displayedText, setDisplayedText] = useState('');

  useEffect(() => {
    let index = 0;
    const timer = setInterval(() => {
      if (index < text.length) {
        setDisplayedText((prev) => prev + text.charAt(index));
        index++;
      } else {
        clearInterval(timer);
      }
    }, speed);

    return () => clearInterval(timer);
  }, [text, speed]);

  return {displayedText};
};

Yukarıdaki kod bloğu, verilen metni karakter karakter işleyerek ekrana basar. useEffect içerisinde setInterval kullanarak her speed milisaniyede bir metni güncelliyoruz. return kısmındaki temizleme fonksiyonu (cleanup function), bileşen ekrandan kaldırıldığında zamanlayıcıyı durdurarak bellek sızıntılarını önler.

Adım 2: İmleç (Cursor) Efekti Ekleyerek Görseli Tamamlama

Yazı yazdırma efektinin olmazsa olmazı, yazının sonunda yanıp sönen bir imleçtir. Bu imleç, uygulamanın bir terminal gibi görünmesini sağlar. CSS kullanarak bu imleci kolayca oluşturabiliriz.

.cursor {
  display: inline-block;
  width: 2px;
  height: 1.2em;
  background-color: black;
  animation: blink 1s step-end infinite;
}

@keyframes blink {
  50% { opacity: 0; }
}

CSS içerisinde @keyframes kullanarak imlecin 1 saniyelik periyotlarla görünürlüğünü değiştiriyoruz. step-end kullanımı, animasyonun yumuşak bir geçiş yerine anlık olarak yanıp sönmesini sağlar.

Adım 3: Çoklu Metin Desteği ve Döngüsel Yazdırma

Genellikle kullanıcılar tek bir metin yerine, sırayla değişen bir metin dizisi görmek ister. Bunun için metinleri bir dizi olarak alıp, her metin bittiğinde bir sonrakine geçen bir yapı kurmalıyız.

const MultiTypewriter = ({ texts, speed = 100 }) => {
  const [index, setIndex] = useState(0);
  const [displayedText, setDisplayedText] = useState('');

  useEffect(() => {
    let charIndex = 0;
    const timer = setInterval(() => {
      if (charIndex < texts[index].length) {
        setDisplayedText(texts[index].substring(0, charIndex + 1));
        charIndex++;
      } else {
        clearInterval(timer);
        setTimeout(() => setIndex((prev) => (prev + 1) % texts.length), 2000);
      }
    }, speed);

    return () => clearInterval(timer);
  }, [index, texts, speed]);

  return 
{displayedText}|
; };

Bu örnekte, texts dizisi üzerinden dönüyoruz. Bir metin tamamlandığında 2 saniyelik bir bekleme süresi (setTimeout) ekleyerek metinlerin birbirini takip etmesini sağlıyoruz. % texts.length mantığı, dizinin sonuna gelindiğinde başa dönülmesini sağlar.

Adım 4: Performans ve Optimizasyon İpuçları

React uygulamalarında useEffect içerisinde sürekli çalışan zamanlayıcılar, gereksiz render işlemlerine neden olabilir. Performans için useRef kullanarak güncel indeks değerlerini takip edebilir veya memoization tekniklerini kullanabilirsiniz.

Yöntem Avantaj Dezavantaj
setInterval Basit ve anlaşılır Zamanlama kaymaları olabilir
requestAnimationFrame Ekran tazeleme ile uyumlu Karmaşık yapı

Büyük metin bloklarında substring kullanmak yerine, karakter dizisini yönetmek daha verimli olabilir. Ayrıca, kullanıcı sayfadan ayrıldığında tüm zamanlayıcıların temizlendiğinden emin olun.

Güvenlik Uyarısı: Eğer yazı yazdırma efektini kullanıcı girdileriyle dinamik olarak oluşturuyorsanız, XSS (Cross-Site Scripting) saldırılarına karşı dikkatli olun. Kullanıcıdan gelen metni doğrudan HTML olarak render etmeyin; her zaman metin düğümü (text node) olarak işleyin.

Adım 5: Gelişmiş Özelleştirme ve Hız Kontrolü

Yazı yazdırma hızını dinamik hale getirmek, uygulamanızın daha doğal görünmesini sağlar. Örneğin, bir noktalama işaretinden sonra hızı yavaşlatmak profesyonel bir dokunuştur.

const getSpeed = (char) => {
  if (char === '.' || char === ',') return 500;
  return 100;
};

// useEffect içerisinde:
const currentSpeed = getSpeed(texts[index][charIndex]);
const timer = setTimeout(() => { /* yazdırma mantığı */ }, currentSpeed);

Bu yöntemle, metin içerisindeki özel karakterlere göre hızı manipüle edebilirsiniz. setInterval yerine setTimeout kullanarak her adımda bir sonraki adımın süresini dinamik olarak belirlemek çok daha esnek bir yapı sunar.

Sıkça Sorulan Sorular

Yazı yazdırma efekti SEO'yu etkiler mi?

Doğrudan bir etkisi yoktur ancak metinleriniz DOM içerisinde yer aldığı sürece arama motorları tarafından indekslenir. Yine de önemli içeriklerinizi animasyona bağımlı kılmadan statik olarak sunmanız daha güvenlidir.

Mobil cihazlarda performans sorunu yaşanır mı?

Hayır, ancak çok uzun metinlerde ve sık render işlemlerinde pil tüketimini artırabilir. Animasyonları requestAnimationFrame ile optimize etmek mobil cihazlarda daha akıcı sonuçlar verir.

Aynı sayfada birden fazla yazı yazdırma efekti kullanabilir miyim?

Evet, oluşturduğumuz bileşenleri farklı props değerleri ile birden fazla kez çağırabilirsiniz. Her bileşen kendi state ve timer değerine sahip olduğu için birbirlerini etkilemezler.

Yazı silme efekti (backspace) nasıl eklenir?

Yazı silme efekti için mevcut state'i azaltan bir useEffect döngüsü daha eklemeniz gerekir. Karakter sayısı sıfıra indiğinde yönü tekrar yazdırmaya çeviren bir bayrak (flag) değişkeni kullanabilirsiniz.

Bu efekt için kütüphane kullanmalı mıyım?

Eğer çok karmaşık (yazı silme, farklı renkler, duraklatma) bir yapı istiyorsanız react-typewriter-effect gibi kütüphaneler kullanılabilir. Ancak basit ve performanslı bir çözüm için yukarıdaki yöntem en sağlıklısıdır.

Yazı Yazdırma Efektlerinde Erişilebilirlik (Accessibility) Standartları

Dinamik olarak değişen metinler, ekran okuyucu kullanan kullanıcılar için kafa karıştırıcı olabilir. Yazı yazdırma efekti uygularken, metnin sürekli değişmesi ekran okuyucunun içeriği sürekli yeniden okumasına veya hiç okuyamamasına neden olabilir. Bu durumu yönetmek için ARIA (Accessible Rich Internet Applications) etiketlerini doğru kullanmalıyız.

Metin alanını aria-live özelliği ile işaretleyerek, tarayıcının içeriği nasıl duyuracağını kontrol edebilirsiniz. İşte erişilebilir bir yapı için örnek uygulama:

// Erişilebilir Yazı Yazdırma Bileşeni
const AccessibleTypewriter = ({ text }) => {
  return (
    
Görüntülenen metin: {text}
); };

Burada aria-live="polite" kullanımı, ekran okuyucunun mevcut işlemi bitirdikten sonra değişikliği bildirmesini sağlar. aria-hidden="true" ise imleç karakterinin ekran okuyucu tarafından gereksiz yere seslendirilmesini engeller.

Büyük Ölçekli Uygulamalarda Yazı Yazdırma Efektinin Test Edilmesi

Karmaşık React uygulamalarında, zamanlayıcılar (setTimeout veya setInterval) bazen test süreçlerinde "flaky" (kararsız) sonuçlara yol açabilir. Jest ve React Testing Library kullanarak bu efektin doğruluğunu test etmek için Fake Timers mekanizmasını kullanmalısınız.

Aşağıdaki örnek, zamanlayıcıyı manuel olarak ilerleterek metnin doğru zamanda güncellenip güncellenmediğini kontrol eder:

import { render, act } from '@testing-library/react';
import Typewriter from './Typewriter';

jest.useFakeTimers();

test('metin belirli bir sürede yazılıyor mu?', () => {
  const { getByText } = render();
  
  act(() => {
    jest.advanceTimersByTime(100);
  });
  
  expect(getByText('M')).toBeInTheDocument();
  
  act(() => {
    jest.advanceTimersByTime(500);
  });
  
  expect(getByText('Merhaba')).toBeInTheDocument();
});

Bu test yöntemi, bileşeninizin zamanlama mantığının doğru çalıştığını doğrular ve üretim ortamında oluşabilecek beklenmedik render hatalarının önüne geçer. Testlerinizde act fonksiyonunu kullanmak, React'in durum güncellemelerini senkronize bir şekilde işlemesini garanti eder.

Performans İzleme ve Bellek Sızıntılarını Önleme

Yazı yazdırma efektleri sürekli useEffect tetiklediği için, bileşen unmount olduğunda (sayfadan kaldırıldığında) zamanlayıcıyı temizlemek hayati önem taşır. Aksi takdirde, arka planda çalışan bir setTimeout, bellek sızıntısına (memory leak) veya "Warning: Can't perform a React state update on an unmounted component" hatasına yol açar.

Hata Türü Çözüm Yolu
Bellek Sızıntısı return () => clearTimeout(timerId); kullanın.
Gereksiz Render useMemo veya useCallback ile fonksiyonları sabitleyin.
Performans Kaybı CSS animasyonları ile JS animasyonlarını kıyaslayın; ağır iş yükü için CSS tercih edin.

Eğer uygulamanızda çok sayıda yazı yazdırma efekti aynı anda çalışıyorsa, requestAnimationFrame kullanarak tarayıcının yenileme hızıyla (refresh rate) uyumlu bir döngü kurmak, setTimeout kullanmaktan çok daha akıcı bir performans sunacaktır.

Sonuç

React ile yazı yazdırma efekti oluşturmak, bileşen yaşam döngüsü ve zamanlayıcı yönetimi konusunda harika bir pratik sağlar. Bu rehberde öğrendiğiniz yöntemleri kullanarak, kullanıcılarınız için etkileyici karşılama ekranları tasarlayabilirsiniz. Bir sonraki adım olarak, bu bileşene "yazı silme" (backspace) özelliğini ekleyerek daha dinamik bir terminal deneyimi oluşturmayı deneyebilirsiniz. Kod güvenliği konusunda her zaman kullanıcı girdilerini temizlemeyi ve gereksiz render işlemlerinden kaçınmayı unutmayın.

Not: Bu rehberdeki kod örnekleri, React 18+ standartlarına göre düzenlenmiştir ve üretim ortamında kullanılabilir.

Bu yazıya tepkinizi paylaşın:
Burak Şahin

Verimlilik ve organizasyon üzerine uzmanlaşmış bir yazarım. Karmaşık görevleri yönetilebilir parçalara bölerek okuyucunun zamanını doğru kullanmasını sağlıyorum.

Yorumlar (0)

Yorum Yaz