Gereksinimler ve Ön Hazırlık
Projeye başlamadan önce sisteminizde Node.js'in güncel bir sürümünün (LTS) yüklü olduğundan emin olmalısınız. React projenizi oluşturmak için Vite kullanmanızı öneririm; zira Vite, hızlı geliştirme sunucusu ve optimize edilmiş yapısıyla modern React projeleri için standarttır.
Projenizi başlatmak için terminalinizde şu komutları çalıştırın:
npm create vite@latest dinamik-takvim -- --template react
cd dinamik-takvim
npm install
npm run dev
Bu adımlar, projenizin temel dizin yapısını oluşturacak ve geliştirme sunucusunu ayağa kaldıracaktır. Takvim bileşenimizi oluştururken herhangi bir CSS kütüphanesi yerine saf CSS veya isteğe bağlı olarak Tailwind CSS kullanabilirsiniz. Biz bu örnekte modüler CSS yaklaşımını tercih edeceğiz.
Takvim Mantığını Anlamak: Tarih Hesaplamaları
Dinamik bir takvim oluşturmanın temelinde, seçilen ayın kaç gün çektiğini ve ayın ilk gününün hangi haftanın gününe denk geldiğini hesaplamak yatar. JavaScript Date nesnesi, yıl ve ay parametrelerini alarak ayın günlerini yönetmemize olanak tanır.
Aşağıdaki kod örneği, bir ayın takvim görünümünü oluşturmak için gerekli olan temel veriyi nasıl hazırladığımızı göstermektedir:
const getDaysInMonth = (year, month) => {
return new Date(year, month + 1, 0).getDate();
};
const getFirstDayOfMonth = (year, month) => {
return new Date(year, month, 1).getDay();
};
Bu fonksiyonlar, takvim ızgarasını (grid) oluştururken hangi günlerin boş bırakılacağını ve toplamda kaç kutucuk oluşturulacağını belirlememizi sağlar. new Date(year, month + 1, 0) kullanımı, bir sonraki ayın 0. gününe (yani mevcut ayın son gününe) giderek ayın kaç gün çektiğini bulmamızı sağlar.
React Bileşen Yapısı ve Durum Yönetimi
Takvim bileşenimizin mevcut yılı ve ayı tutan bir duruma (state) ihtiyacı vardır. Kullanıcı "ileri" veya "geri" butonlarına bastığında, bu durum güncellenerek takvimin dinamik olarak yeniden render edilmesi sağlanır.
İşte takvimimizin temel bileşen yapısı:
import { useState } from 'react';
const Calendar = () => {
const [currentDate, setCurrentDate] = useState(new Date());
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
const nextMonth = () => {
setCurrentDate(new Date(year, month + 1, 1));
};
const prevMonth = () => {
setCurrentDate(new Date(year, month - 1, 1));
};
return (
Önceki
{year} / {month + 1}
Sonraki
);
};
Burada useState kullanarak mevcut tarih bilgisini tutuyoruz. Kullanıcı etkileşimi ile tarih nesnesini değiştirdiğimizde, React bileşeni otomatik olarak güncel ay verisiyle yeniden render eder.
Takvim Izgarasını Oluşturma (Adım Adım)
Takvim günlerini ekrana basmak için bir dizi oluşturup bu diziyi map metodu ile dönmemiz gerekir. Takvimin 7 sütunlu (Pazartesi-Pazar) yapısını korumak için boş günleri de hesaba katmalıyız.
const renderDays = () => {
const daysInMonth = getDaysInMonth(year, month);
const firstDay = getFirstDayOfMonth(year, month);
const days = [];
// Ayın ilk gününden önceki boşluklar
for (let i = 0; i < firstDay; i++) {
days.push();
}
// Ayın günleri
for (let d = 1; d {
return renderDays();
}, [currentDate]);
Bu sayede currentDate değişmediği sürece takvim günleri yeniden hesaplanmaz.
Sıkça Sorulan Sorular
Takvimde seçili günü nasıl işaretlerim?
Bileşen durumuna selectedDate adında bir değişken ekleyin. Günleri render ederken, mevcut günün selectedDate ile eşleşip eşleşmediğini kontrol edin ve eşleşiyorsa CSS sınıfı olarak 'active' ekleyin.
Takvime etkinlikleri nasıl eklerim?
Etkinlikleri bir dizi objesi olarak tutun ve günleri render ederken, o güne ait bir etkinlik olup olmadığını kontrol ederek ilgili günün içine bir div veya span etiketi yerleştirin.
Mobil uyumluluk için ne yapmalıyım?
CSS Grid kullanarak grid-template-columns: repeat(7, 1fr) yapısını kurun. Mobil ekranlarda font boyutlarını küçülterek ve gün isimlerini kısaltarak (Pzt, Sal vb.) yer kazanabilirsiniz.
Farklı dillerde takvim nasıl yapılır?
JavaScript'in Intl.DateTimeFormat API'sini kullanarak gün ve ay isimlerini kullanıcının tarayıcı diline göre dinamik olarak çekebilirsiniz.
Neden kütüphane yerine kendim yazmalıyım?
Projenizin özel bir tasarım dili varsa veya sadece takvimin çok küçük bir kısmını (örneğin sadece tarih seçimi) kullanacaksanız, kütüphane yükü projenizi hantallaştırır. Kendi bileşeniniz tam olarak ihtiyacınız olanı yapar.
Takvim Bileşeninde Performans Optimizasyonu
Dinamik takvimler, özellikle her ay geçişinde veya etkinlik güncellemelerinde yeniden render (yeniden çizim) süreçleri nedeniyle performans darboğazlarına yol açabilir. React'in memoization yeteneklerini kullanarak, gereksiz render işlemlerini engelleyebilir ve uygulamanızın akıcılığını koruyabilirsiniz.
Özellikle takvim ızgarasındaki hücrelerin (günlerin) her biri birer bileşen ise, React.memo kullanarak sadece değişen günlerin güncellenmesini sağlayın.
import React, { memo } from 'react';
const DayCell = memo(({ day, events }) => {
console.log(`Render: ${day}`);
return (
{day}
{events.map(event => {event.title})}
);
});
export default DayCell;
Bu yaklaşım, takvimdeki ay değiştiğinde veya etkinlik listesi güncellendiğinde, sadece ilgili hücrelerin DOM üzerinde güncellenmesini sağlar. Büyük veri setleri ile çalışırken, etkinlikleri bir useMemo kancası ile tarih bazlı gruplandırarak filtreleme maliyetini düşürmek de kritik bir adımdır.
Takvim Bileşenleri İçin Test Stratejileri
Takvim gibi tarih hesaplamalarının yoğun olduğu bileşenlerde, Edge Case (uç durum) testleri hayati önem taşır. Özellikle artık yıllar, ay sonları ve geçiş dönemleri için birim testleri (unit tests) yazmalısınız.
Jest ve React Testing Library kullanarak, takvimin doğru ay ve günleri gösterdiğinden emin olabilirsiniz:
import { render, screen } from '@testing-library/react';
import Calendar from './Calendar';
test('takvim doğru ay ismini göstermeli', () => {
render();
const monthLabel = screen.getByText(/Ekim 2023/i);
expect(monthLabel).toBeInTheDocument();
});
test('takvim ızgarası 30 günden fazla hücre içermemeli', () => {
const { container } = render();
const days = container.querySelectorAll('.day-cell');
expect(days.length).toBeLessThanOrEqual(42);
});
Testlerinizi yazarken date-fns veya dayjs gibi kütüphaneler kullanıyorsanız, bu kütüphanelerin sunduğu mock fonksiyonlarını kullanarak zamanı dondurabilir (time-travel testing), böylece testlerinizin her zaman aynı sonucu vermesini sağlayabilirsiniz.
İleri Düzey İpuçları
- Keyboard Navigation: Erişilebilirlik (A11y) için takvim üzerinde ok tuşlarıyla gün seçimi yapılabilmesini sağlayın.
- Virtualization: Eğer takviminiz sonsuz kaydırma (infinite scroll) özelliğine sahipse,
react-windowgibi kütüphanelerle sadece görünür olan ayları render edin. - Zaman Dilimi (Timezone): Sunucu ile istemci arasındaki saat farklarını yönetmek için her zaman
UTCformatını temel alın ve kullanıcıya gösterirken yerel saate çevirin.
Sonuç
React ile dinamik bir takvim bileşeni oluşturmak, hem JavaScript tarih nesnelerine hakimiyetinizi artırır hem de uygulamanızın bağımlılıklarını minimize eder. Bu rehberde öğrendiğiniz temel mantığı kullanarak, üzerine etkinlik ekleme, sürükle-bırak özelliği veya farklı görünüm modları (haftalık/aylık) gibi gelişmiş özellikler inşa edebilirsiniz.
Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamında kullanmadan önce güvenlik açıklarını (XSS, veri doğrulama vb.) kontrol etmeli ve projenizin özel gereksinimlerine göre test etmelisiniz.
Bir sonraki adım olarak, bu takvimi bir API ile entegre ederek veritabanından etkinlikleri çekmeyi ve kullanıcıların kendi etkinliklerini oluşturabileceği bir form yapısı eklemeyi deneyebilirsiniz. Başarılar dilerim.


Yorumlar (0)
Yorum Yaz