Gereksinimler ve Ön Hazırlık
Bu projeye başlamadan önce sisteminizde Node.js'in güncel bir sürümünün (LTS) yüklü olması gerekmektedir. React uygulaması oluşturmak için Vite gibi modern bir yapılandırıcı kullanmanızı öneririz. Aşağıdaki adımları takip ederek geliştirme ortamınızı hazırlayabilirsiniz.
- Node.js 20.x veya üzeri bir sürüm.
- React 19.x veya üzeri bir sürüm.
- Temel düzeyde JavaScript (ES6+) ve React Hooks bilgisi.
Projenizi başlatmak için terminalinizde şu komutları çalıştırarak boş bir React projesi oluşturabilirsiniz:
npm create vite@latest typing-effect-app -- --template react
cd typing-effect-app
npm install
npm run dev
Bu komutlar, projenizin temel dizin yapısını oluşturacak ve yerel sunucunuzu ayağa kaldıracaktır. Artık kodlamaya başlamaya hazırsınız.
Adım Adım Yazdırma Efekti Mantığı
Yazdırma efektinin temel mantığı, bir metin dizisini parçalara ayırıp, belirli aralıklarla (set interval) bu parçaları bir state değişkenine eklemekten geçer. React'te bu işlemi yönetmek için useState ile metni, useEffect ile de zamanlayıcıyı kontrol ederiz.
Öncelikle, temel bir bileşen yapısı oluşturalım. Bu bileşen, kendisine verilen bir metni alacak ve karakter karakter ekrana yazdıracaktır.
import { useState, useEffect } from 'react';
const Typewriter = ({ text, speed = 100 }) => {
const [displayedText, setDisplayedText] = useState('');
useEffect(() => {
let i = 0;
const timer = setInterval(() => {
if (i < text.length) {
setDisplayedText((prev) => prev + text.charAt(i));
i++;
} else {
clearInterval(timer);
}
}, speed);
return () => clearInterval(timer);
}, [text, speed]);
return {displayedText};
};
Bu kodda useEffect içerisinde bir setInterval tanımladık. Her zaman aralığında displayedText state'ini güncelleyerek metnin parça parça ekrana gelmesini sağladık. return kısmındaki temizleme fonksiyonu, bileşen ekrandan kaldırıldığında zamanlayıcının durmasını sağlar; bu, bellek sızıntılarını önlemek için kritiktir.
Dinamik ve Çoklu Metin Desteği
Sadece tek bir cümleyi yazdırmak yerine, bir dizi metni sırayla yazdıran ve silen daha gelişmiş bir yapı kurmak isteyebilirsiniz. Bunun için state içerisinde hem mevcut metni hem de hangi metnin yazıldığını takip eden bir sayaç tutmamız gerekir.
const MultiTypewriter = ({ phrases, speed = 100 }) => {
const [text, setText] = useState('');
const [index, setIndex] = useState(0);
useEffect(() => {
let charIndex = 0;
const timer = setInterval(() => {
setText(phrases[index].substring(0, charIndex + 1));
charIndex++;
if (charIndex === phrases[index].length) {
clearInterval(timer);
}
}, speed);
return () => clearInterval(timer);
}, [index, phrases, speed]);
return {text};
};
Bu yaklaşım, phrases dizisindeki her bir ifadeyi sırayla işler. index state'i değiştikçe useEffect tetiklenir ve yeni metin yazılmaya başlar.
Performans ve Optimizasyon İpuçları
Yazdırma efekti gibi sürekli state güncellemesi yapan bileşenlerde, gereksiz yeniden render (re-render) işlemlerinden kaçınmak önemlidir. React.memo kullanarak bileşenin sadece prop'ları değiştiğinde güncellenmesini sağlayabilirsiniz.
Aşağıdaki tabloda, farklı yazdırma yöntemlerinin avantaj ve dezavantajlarını görebilirsiniz:
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| setInterval Hook | Basit ve anlaşılır | Hassas zamanlama sorunları |
| CSS Animasyonları | Performanslı (GPU kullanımı) | Dinamik metinlerde zor |
| requestAnimationFrame | Akıcı ve performanslı | Karmaşık uygulama yapısı |
Güvenlik ve Erişilebilirlik Uyarıları
Kritik Uyarı: Yazdırma efektleri, ekran okuyucular (screen readers) için kafa karıştırıcı olabilir. Metin sürekli değiştiği için ekran okuyucu her karakter değişimini okumaya çalışabilir. Bunu engellemek için
aria-live="polite"özniteliğini kullanarak, metnin sadece tamamlandığında veya belirli aralıklarla okunmasını sağlamalısınız.
Güvenlik açısından, dışarıdan gelen verileri (API'den gelen metinler gibi) doğrudan yazdırmadan önce temizlediğinizden emin olun. XSS (Cross-Site Scripting) saldırılarına karşı, metni her zaman textContent olarak işleyen React'in varsayılan davranışını bozacak dangerouslySetInnerHTML kullanımından kaçının.
Sıkça Sorulan Sorular
Yazdırma efekti mobil cihazlarda pil tüketimini artırır mı?
Çok sık state güncellemesi yapmak, özellikle düşük seviyeli cihazlarda pil tüketimini bir miktar artırabilir. Animasyon süresini çok kısa tutmamak ve gereksiz render'ları önlemek bu sorunu minimize eder.
Metin bittikten sonra imleç (cursor) nasıl eklenir?
CSS kullanarak span elementine border-right özelliği ekleyebilir ve bir @keyframes animasyonu ile bu kenarlığı yanıp söndürebilirsiniz.
Aynı anda birden fazla yerde bu efekti kullanabilir miyim?
Evet, bileşeni modüler tasarladığınız için istediğiniz kadar instance oluşturup farklı metinler ve hız değerleri ile kullanabilirsiniz.
Yazı yazılırken ses efekti eklemek mümkün mü?
Evet, Audio API'sini kullanarak her karakter eklendiğinde kısa bir tıklama sesi tetikleyebilirsiniz. Ancak kullanıcı deneyimi açısından bunu bir ayar ile kapatılabilir kılmanız önerilir.
Bu efekt SEO'yu etkiler mi?
Arama motorları JavaScript'i işleyebildiği için metnin içeriği indekslenir. Ancak metnin tamamının sayfada göründüğünden emin olmak için içerik yükleme stratejinize dikkat etmelisiniz.
Özel Bir useTypewriter Hook'u ile Modülerlik
Daha önce oluşturduğumuz mantığı, bileşenlerimizin içine gömmek yerine yeniden kullanılabilir bir Custom Hook yapısına taşımak, kodunuzun temizliğini (clean code) artırır. Bu sayede, uygulamanın farklı sayfalarında aynı mantığı tekrar yazmak zorunda kalmazsınız.
import { useState, useEffect } from 'react';
export const useTypewriter = (text, speed = 100) => {
const [displayedText, setDisplayedText] = useState("");
const [index, setIndex] = useState(0);
useEffect(() => {
if (index < text.length) {
const timeout = setTimeout(() => {
setDisplayedText((prev) => prev + text.charAt(index));
setIndex(index + 1);
}, speed);
return () => clearTimeout(timeout);
}
}, [index, text, speed]);
return displayedText;
};
Bu hook'u bir bileşen içerisinde şu şekilde kolayca çağırabilirsiniz:
const HeroSection = () => {
const title = useTypewriter("Merhaba, dünyayı keşfetmeye hazır mısın?", 75);
return
{title}
;
};
İleri Seviye Optimizasyon: Web Workers ve Render Yönetimi
Yazı yazdırma efekti gibi sürekli durum (state) güncelleyen işlemler, büyük ölçekli uygulamalarda gereksiz re-render süreçlerine yol açabilir. Özellikle sayfanın geri kalanında ağır hesaplamalar yapılıyorsa, bu durum arayüzde takılmalara neden olabilir.
Performans İçin İpuçları
- React.memo Kullanımı: Yazı yazılan bileşeni
React.memoile sarmalayarak, üst bileşenden gelen gereksiz güncellemelerin bu bileşeni tekrar tetiklemesini engelleyin. - useCallback ve useMemo: Eğer yazdırma hızını veya metin içeriğini dinamik olarak değiştiren fonksiyonlarınız varsa, bunları
useCallbackile sarmalayarak referans eşitliğini koruyun. - DOM Manipülasyonu: Çok uzun metinlerde her karakter için state güncellemesi yapmak yerine, metni bir
refüzerinden doğrudan DOM'a yazmayı düşünebilirsiniz, ancak bu React'in deklaratif yapısıyla çelişebileceği için sadece ekstrem performans sorunlarında tercih edilmelidir.
Hata Ayıklama (Debugging) Stratejileri
Geliştirme aşamasında efektin beklediğiniz gibi çalışmadığı durumlarla karşılaşabilirsiniz. İşte yaygın sorunlar ve çözümleri:
| Sorun | Olası Neden | Çözüm |
|---|---|---|
| Metin aniden beliriyor | useEffect bağımlılık dizisi eksik | Bağımlılık dizisine metin ve index değerlerini ekleyin. |
| Hız tutarsızlığı | setInterval kullanımı | setInterval yerine setTimeout kullanarak her adımda zamanlamayı kontrol edin. |
| Bellek sızıntısı (Memory Leak) | Cleanup fonksiyonu eksik | return () => clearTimeout(timeout) satırını mutlaka ekleyin. |
Bu teknikleri uygulayarak, sadece görsel olarak etkileyici değil, aynı zamanda teknik açıdan sağlam ve ölçeklenebilir bir yazı yazdırma modülüne sahip olabilirsiniz.
Sonuç
React ile dinamik bir yazı yazdırma efekti oluşturmak, hem React'in state yönetimi yeteneklerini anlamak hem de kullanıcı deneyimini zenginleştirmek için harika bir pratik çalışmasıdır. Bu rehberde öğrendiğiniz useEffect ve setInterval kullanımı, daha karmaşık animasyonlar ve zaman tabanlı işlemler için temel teşkil eder.
Yasal Uyarı: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce, özellikle kullanıcıdan alınan verilerin işlendiği durumlarda gerekli güvenlik taramalarını yapmanız ve XSS gibi güvenlik açıklarına karşı önlemler almanız sorumluluğunuzdadır.
Bir sonraki adım olarak, bu efekti bir kütüphane kullanmadan kendi özel hook'unuzu (custom hook) yazarak daha modüler hale getirmeyi deneyebilirsiniz. Böylece useTypewriter şeklinde bir kanca ile uygulamanızın her yerinde bu özelliği kolayca kullanabilirsiniz.

Yorumlar (0)
Yorum Yaz