Gereksinimler ve Ön Hazırlık
Çalışmaya başlamadan önce bilgisayarınızda Node.js'in en güncel LTS sürümünün yüklü olduğundan emin olun. Projenizde React 19 veya üzeri bir sürüm kullanmanız, modern hook yapılarını daha verimli kullanmanızı sağlayacaktır. İhtiyacımız olan temel paketleri projenize şu şekilde ekleyebilirsiniz:
npm install i18next react-i18next i18next-browser-languagedetector
Bu paketler, uygulamanın dilini algılamak, çevirileri yönetmek ve dil değişimlerini React bileşenlerine yansıtmak için endüstri standardı olan araçlardır. Kurulum sonrası projenizin kök dizininde bir i18n.js yapılandırma dosyası oluşturarak işe başlayacağız.
i18next Yapılandırması ve Dil Dosyalarının Hazırlanması
Çoklu dil desteği için öncelikle çeviri dosyalarımızı JSON formatında hazırlamalıyız. Bu dosyalar, arama terimlerinizin ve uygulama metinlerinizin farklı dillerdeki karşılıklarını tutacaktır. Aşağıdaki örnekte, locales/tr/translation.json ve locales/en/translation.json dosyalarınızın yapısını görebilirsiniz.
// locales/tr/translation.json
{
"search_placeholder": "Ürünleri ara...",
"no_results": "Sonuç bulunamadı."
}
// locales/en/translation.json
{
"search_placeholder": "Search products...",
"no_results": "No results found."
}
Bu JSON dosyaları, uygulamanızın dinamik olarak dil değiştirdiğinde arama kutusunun etiketlerini otomatik olarak güncellemesini sağlar. i18next konfigürasyonunu ise şu şekilde yapmalısınız:
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
i18n.use(LanguageDetector).use(initReactI18next).init({
resources: {
tr: { translation: require('./locales/tr/translation.json') },
en: { translation: require('./locales/en/translation.json') }
},
fallbackLng: 'tr',
interpolation: { escapeValue: false }
});
Dinamik Arama Bileşeninin Oluşturulması
Arama bileşeni, kullanıcının girdiği metni dinlemeli ve bu metne göre mevcut veri setini filtrelemelidir. Burada önemli olan, arama işleminin dil değişikliğinden etkilenmemesi, ancak arama sonuçlarının dil bazlı çevirilerle eşleşmesidir. İşte temel arama bileşeni yapısı:
import React, { useState, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
const SearchComponent = ({ data }) => {
const { t } = useTranslation();
const [query, setQuery] = useState('');
const filteredData = useMemo(() => {
return data.filter(item =>
item.name.toLowerCase().includes(query.toLowerCase())
);
}, [query, data]);
return (
setQuery(e.target.value)}
/>
{filteredData.length > 0 ? (
filteredData.map(item => {item.name})
) : (
{t('no_results')}
)}
);
};
Burada useMemo hook'unu kullanarak, her render işleminde filtreleme fonksiyonunun yeniden hesaplanmasını engelliyoruz. Bu, uygulamanızın performansını doğrudan artıran bir optimizasyondur.
Çoklu Dil Destekli Veri Filtreleme Stratejileri
Eğer verileriniz de çoklu dil desteğine sahipse (örneğin ürün isimleri hem Türkçe hem İngilizce olarak veritabanında tutuluyorsa), arama mantığınızı buna göre güncellemeniz gerekir. Aşağıdaki tablo, farklı ölçeklerdeki arama yöntemlerini karşılaştırmaktadır.
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Client-side (İstemci) | Çok hızlı, sunucu yükü yok. | Büyük veri setlerinde yavaşlar. |
| Server-side (Sunucu) | Büyük veriler için ideal. | API gecikmesi ve sunucu maliyeti. |
| Hibrit | Dengeli performans. | Karmaşık mimari. |
Güvenlik ve Performans İpuçları
Arama kutuları, XSS (Cross-Site Scripting) saldırıları için potansiyel giriş noktalarıdır. Kullanıcıdan alınan veriyi doğrudan DOM'a yansıtırken her zaman temizleme (sanitization) işlemlerini yapmalısınız. Ayrıca, kullanıcının her tuş vuruşunda filtreleme yapması yerine "Debounce" tekniğini kullanmak, kaynak tüketimini ciddi oranda azaltır.
Kritik Uyarı: Kullanıcı girdilerini asla doğrudan HTML olarak render etmeyin. Eğer arama sonuçlarında kullanıcı girdisini gösteriyorsanız, DOMPurify gibi kütüphaneler kullanarak XSS riskini minimize edin. Ayrıca, üretim ortamında (production) büyük veri setlerini istemci tarafında tutmak yerine mutlaka sunucu tarafında filtreleme yapın.
import { debounce } from 'lodash';
const handleSearch = debounce((value) => {
// API çağrısı veya filtreleme mantığı
}, 300);
Sıkça Sorulan Sorular
Arama sonuçlarını dil değişimine göre anında nasıl güncellerim?
React'te i18next kullandığınızda dil değişimi otomatik olarak tetiklenir. useTranslation hook'u sayesinde bileşenleriniz dil değiştiğinde otomatik olarak yeniden render olur ve t() fonksiyonu güncel dildeki metni getirir.
Büyük veri setlerinde React arama performansı nasıl korunur?
Büyük listeler için react-window veya react-virtualized gibi kütüphanelerle "windowing" (sadece ekranda görünen öğeleri render etme) tekniğini kullanın. Bu, DOM üzerindeki yükü ciddi oranda hafifletir.
Arama terimlerini URL'de saklamalı mıyım?
Evet, özellikle paylaşılabilir arama sonuçları için arama terimini URLSearchParams ile URL'de tutmak (örneğin: /urunler?q=kamera) en iyi pratiktir.
Dinamik dil yükleme (lazy loading) mümkün mü?
Evet, i18next-http-backend kullanarak dil dosyalarını sadece ihtiyaç duyulduğunda sunucudan çekebilirsiniz, bu da uygulamanın ilk açılış hızını artırır.
Arama sonuçlarında vurgulama (highlighting) nasıl yapılır?
Arama terimini içeren metin kısmını bir span etiketiyle sarıp CSS ile arka plan rengi vererek basit bir vurgulama mekanizması kurabilirsiniz.
Arama Deneyimini İleri Seviyeye Taşıyacak UX İpuçları
Kullanıcı deneyimini (UX) iyileştirmek için sadece arama sonuçlarını listelemek yeterli değildir. Özellikle çoklu dil desteği olan uygulamalarda, arama sonuçlarının kullanıcıya nasıl sunulduğu, uygulamanın profesyonellik seviyesini belirler. Aşağıdaki teknikler, arama arayüzünüzü daha sezgisel hale getirecektir.
Boş Durum (Empty State) Yönetimi
Kullanıcı arama yaptığında sonuç bulunamadığında, sadece "Sonuç yok" demek yerine, kullanıcının diline uygun öneriler sunmak veya arama terimini temizlemesi için bir buton eklemek önemlidir. i18next ile bu durumu şu şekilde yönetebilirsiniz:
const SearchResults = ({ results, query }) => {
const { t } = useTranslation();
if (results.length === 0 && query.length > 0) {
return (
{t('search.noResults', { term: query })}
clearSearch()}>{t('search.clear')}
);
}
// ... sonuç listeleme
};
Arama Gecikmesini (Debouncing) Optimize Etme
Her tuş vuruşunda arama fonksiyonunu çalıştırmak, özellikle büyük veri setlerinde ciddi performans kaybına yol açar. lodash.debounce kullanarak, kullanıcının yazmayı bırakmasını bekleyen bir mekanizma kurmak, uygulamanın gereksiz render almasını engeller.
import debounce from 'lodash/debounce';
const handleSearch = useCallback(
debounce((value) => {
setSearchTerm(value);
}, 300),
[]
);
Arama Bileşenleri İçin Birim Testleri
Çoklu dil destekli bir arama bileşeninin hatasız çalıştığından emin olmak için Vitest veya Jest ile test senaryoları yazmak kritik öneme sahiptir. Özellikle dil değişimi (i18n) tetiklendiğinde arama sonuçlarının güncellenip güncellenmediğini kontrol etmelisiniz.
Dil Değişimini Test Etme
Aşağıdaki örnek, arama bileşeninin farklı dillerde doğru metinleri render edip etmediğini doğrulamak için temel bir test yapısını göstermektedir:
import { render, screen } from '@testing-library/react';
import SearchComponent from './SearchComponent';
test('arama kutusu farklı dillerde doğru placeholder gösteriyor', () => {
// İngilizce testi
render();
expect(screen.getByPlaceholderText(/search items/i)).toBeInTheDocument();
// Türkçe testi
render();
expect(screen.getByPlaceholderText(/öğe ara/i)).toBeInTheDocument();
});
Bu testler, uygulamanızın farklı dillerde tutarlı bir kullanıcı deneyimi sunmasını garanti eder. Özellikle dinamik içeriklerin (API'den gelen veriler) çeviri dosyalarıyla çakışmadığından emin olmak için mock verilerle testlerinizi çeşitlendirmeyi unutmayın.
Sonuç
React ile dinamik ve çoklu dil destekli bir arama sistemi kurmak, doğru kütüphane seçimi ve performans odaklı bir yapılandırma ile oldukça verimli bir süreçtir. Bu rehberde öğrendiğiniz i18next entegrasyonu, useMemo ile performans optimizasyonu ve güvenlik önlemleri, profesyonel seviyede bir uygulama geliştirmeniz için temel taşlardır. Bir sonraki adım olarak, arama sonuçlarınızı bir API üzerinden çekmeyi ve arama deneyimini bir "Search-as-you-type" (yazarken ara) yapısına dönüştürmeyi deneyebilirsiniz.

Yorumlar (0)
Yorum Yaz