Gereksinimler ve Ön Hazırlık
Projeye başlamadan önce bilgisayarınızda Node.js'in güncel bir LTS (Long Term Support) sürümünün yüklü olduğundan emin olmalısınız. Modern React projeleri için Vite kullanmak, hızlı bir geliştirme ortamı sunar. Aşağıdaki komutlar ile projenizi başlatabilirsiniz.
# Yeni bir Vite projesi oluşturun
npm create vite@latest markdown-not-defteri -- --template react
cd markdown-not-defteri
npm install
# Markdown işleme kütüphanesini ekleyin
npm install react-markdown remark-gfm
Burada kullandığımız react-markdown, Markdown metinlerini güvenli bir şekilde React bileşenlerine dönüştüren standart bir araçtır. remark-gfm ise GitHub Flavored Markdown (tablolar, görev listeleri vb.) desteğini projeye dahil eder. Bu bağımlılıklar, not defterimizin temel işlevselliğini oluşturur.
Not Defteri Bileşeninin Temel Yapısını Oluşturma
Uygulamamızın temelinde, kullanıcının metin girdiği bir textarea alanı ve bu metnin Markdown olarak işlendiği bir önizleme alanı bulunur. React'in useState hook'unu kullanarak metin içeriğini anlık olarak takip edeceğiz. İşte not defterimizin ana bileşeni:
import React, { useState } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
function NotDefteri() {
const [markdown, setMarkdown] = useState('# Yeni Not\n\nBuraya notlarınızı yazmaya başlayın.');
return (
setMarkdown(e.target.value)}
className="editor"
/>
{markdown}
);
}
export default NotDefteri;
Bu yapıda markdown değişkeni, kullanıcının girdiği ham metni tutar. onChange olayı tetiklendiğinde, state güncellenir ve ReactMarkdown bileşeni otomatik olarak yeniden render edilerek önizlemeyi günceller. Bu, React'in reaktif veri akışının en temel ve etkili kullanımıdır.
Markdown İşleme Yöntemlerinin Karşılaştırılması
Markdown desteği eklerken farklı yaklaşımlar mevcuttur. İhtiyacınıza göre en uygun olanı seçmek için aşağıdaki tabloyu inceleyebilirsiniz:
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| React-Markdown | Güvenli, bileşen bazlı, özelleştirilebilir. | Ek bağımlılık gerektirir. |
| DangerouslySetInnerHTML | Hızlıdır, kütüphane gerektirmez. | XSS saldırılarına açıktır, tehlikelidir. |
| Özel Parser Yazmak | Tam kontrol sağlar. | Bakımı zordur, hata payı yüksektir. |
Veri Kalıcılığı: LocalStorage Kullanımı
Kullanıcının yazdığı notların sayfa yenilendiğinde kaybolmaması için tarayıcının localStorage özelliğini kullanacağız. Bu, verilerin istemci tarafında kalıcı olarak saklanmasını sağlar. useEffect hook'u ile state her değiştiğinde veriyi diske yazacağız.
import { useEffect } from 'react';
// Bileşen içinde:
useEffect(() => {
const savedNote = localStorage.getItem('not-defteri-verisi');
if (savedNote) setMarkdown(savedNote);
}, []);
useEffect(() => {
localStorage.setItem('not-defteri-verisi', markdown);
}, [markdown]);
Bu kod bloğu, uygulama ilk açıldığında localStorage içerisindeki veriyi kontrol eder ve varsa mevcut state'i günceller. İkinci useEffect ise markdown değişkenindeki her değişiklikte veriyi güncel tutar. Bu yöntem, küçük ölçekli not uygulamaları için en verimli çözümdür.
Güvenlik Uyarısı: Kullanıcıdan alınan metinleri doğrudan HTML olarak işlemek (örneğin
dangerouslySetInnerHTMLile) XSS (Cross-Site Scripting) saldırılarına kapı aralar.react-markdownkütüphanesi varsayılan olarak güvenli bir yapı sunar, ancak özel bileşenler eklerken her zaman girdi temizleme (sanitization) işlemlerini göz önünde bulundurun.
Stil ve Kullanıcı Deneyimi İyileştirmeleri
Not defterinin profesyonel görünmesi için CSS Grid veya Flexbox kullanmalıyız. İki sütunlu bir yapı, kullanıcının yazarken aynı anda önizlemeyi görmesini sağlar. Aşağıdaki CSS yapısı, modern bir arayüz için temel oluşturur.
.editor-container {
display: flex;
height: 100vh;
gap: 10px;
}
.editor, .preview {
flex: 1;
padding: 20px;
overflow-y: auto;
}
.editor {
border: 1px solid #ccc;
resize: none;
}
Bu CSS kuralları, ekranı iki eşit parçaya böler. overflow-y: auto özelliği, not uzun olduğunda kaydırma çubuklarının otomatik olarak çıkmasını sağlar. Bu sayede uzun metinlerde bile kullanıcı deneyimi bozulmaz.
Performans Optimizasyonu: Debouncing
Eğer notlarınız çok uzunsa, her tuş vuruşunda Markdown'ı işlemek performans sorunlarına yol açabilir. Bu noktada "Debouncing" (gecikmeli tetikleme) tekniğini kullanmalıyız. Bu teknik, kullanıcı yazmayı bıraktıktan kısa bir süre sonra işlemin gerçekleşmesini sağlar.
import { useState, useEffect } from 'react';
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}
Bu özel hook'u, ReactMarkdown bileşenine giden veriyi süzmek için kullanabilirsiniz. Böylece işlemci yükünü azaltarak uygulamanın daha akıcı çalışmasını sağlarsınız.
Sıkça Sorulan Sorular
Markdown not defterinde resim yükleme desteği nasıl eklenir?
Resim yükleme için bir backend servisine veya Cloudinary gibi bir bulut depolama hizmetine ihtiyacınız vardır. Kullanıcı resmi yüklediğinde dönen URL'yi Markdown formatında () metin alanına ekleyebilirsiniz.
Uygulamayı nasıl canlıya alabilirim?
Vercel veya Netlify gibi platformlar, React projelerini doğrudan GitHub deponuzdan otomatik olarak derleyip yayınlamanıza olanak tanır. "npm run build" komutu ile statik dosyalarınızı oluşturup bu platformlara yükleyebilirsiniz.
Markdown notlarını PDF olarak dışa aktarabilir miyim?
Evet, jspdf veya react-to-print kütüphanelerini kullanarak önizleme alanındaki HTML içeriğini PDF formatına dönüştürebilirsiniz.
Mobil cihazlarda nasıl bir tasarım izlemeliyim?
Mobil ekranlarda iki sütunlu yapıyı tek sütuna düşüren medya sorguları (media queries) kullanmalısınız. Kullanıcıya "Düzenle" ve "Önizleme" arasında geçiş yapabileceği bir sekme yapısı sunmak en iyi pratiktir.
Veri güvenliği için nelere dikkat etmeliyim?
Kullanıcı verilerini yerel tarayıcıda tutmak güvenlidir ancak hassas veriler için mutlaka bir veritabanı ve kullanıcı kimlik doğrulaması (Auth) kullanmalısınız. Asla kullanıcı verilerini şifrelemeden sunucuda tutmayın.
İleri Düzey Özellik: Notlar İçin Arama ve Filtreleme Mekanizması
Not defteri uygulamanız büyüdükçe, kullanıcıların yüzlerce not arasından aradıklarını saniyeler içinde bulmaları kritik bir hale gelir. React'in useMemo kancasını kullanarak, not listesini filtrelemek için performanslı bir arama motoru oluşturabiliriz. Bu yaklaşım, her tuş vuruşunda tüm listeyi yeniden hesaplamak yerine, yalnızca bağımlılıklar değiştiğinde filtreleme işlemini tetikler.
const [searchTerm, setSearchTerm] = useState("");
const filteredNotes = useMemo(() => {
return notes.filter(note =>
note.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
note.content.toLowerCase().includes(searchTerm.toLowerCase())
);
}, [notes, searchTerm]);
Bu kod bloğu, notes dizisi veya searchTerm değişmediği sürece hesaplama yapmaz. Arayüzde ise kullanıcıya anlık geri bildirim veren bir input alanı ekleyerek kullanıcı deneyimini (UX) ciddi oranda artırabilirsiniz.
Uygulama Hata Ayıklama ve Hata Yönetimi (Error Boundaries)
Markdown işleme sırasında oluşabilecek hatalar (örneğin bozuk bir syntax veya kütüphane çakışması), tüm uygulamanın çökmesine neden olabilir. React'in ErrorBoundary yapısını kullanarak, belirli bir notun render edilmesi sırasında oluşan hataları yakalayabilir ve kullanıcıya "Bu not görüntülenemiyor" gibi anlamlı bir mesaj gösterebilirsiniz.
Hata Sınırı Bileşeni Oluşturma
Aşağıdaki örnek, uygulamanızın genelini korumak için kullanabileceğiniz temel bir hata sınırı bileşenidir:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.error("Markdown işleme hatası:", error, errorInfo);
}
render() {
if (this.state.hasError) {
return Not yüklenirken bir hata oluştu.
;
}
return this.props.children;
}
}
Bu bileşeni, Markdown önizleme alanını saran bir sarmalayıcı (wrapper) olarak kullanmak, uygulamanızın çalışma zamanı kararlılığını (runtime stability) garanti altına alır. Özellikle kullanıcıların karmaşık Markdown tabloları veya özel HTML etiketleri girdiği durumlarda bu katman hayati önem taşır.
Performans İçin İleri İpuçları: Lazy Loading
Uygulamanızda kullandığınız Markdown parser kütüphaneleri (örneğin react-markdown) bazen büyük boyutlu olabilir. Eğer sadece not düzenleme sayfasında bu kütüphaneye ihtiyaç duyuyorsanız, React.lazy ve Suspense kullanarak kütüphanenin sadece ihtiyaç duyulduğunda yüklenmesini sağlayabilirsiniz.
const MarkdownPreview = React.lazy(() => import('react-markdown'));
function NoteEditor({ content }) {
return (
);
}
Bu teknik, uygulamanızın ilk açılış süresini (First Contentful Paint) kısaltır ve kullanıcıların daha hızlı bir deneyim yaşamasını sağlar. Özellikle düşük internet hızına sahip mobil kullanıcılar için bu optimizasyon, uygulamanızın profesyonellik seviyesini belirleyen temel bir faktördür.
Sonuç
React ile Markdown destekli bir not defteri geliştirmek, hem React'in state yönetimi yeteneklerini hem de üçüncü taraf kütüphanelerin entegrasyonunu anlamak için harika bir projedir. Bu rehberde, temel bir editörden başlayarak veri kalıcılığı, stil ve performans optimizasyonuna kadar profesyonel bir akış izledik. Bir sonraki adım olarak, notları kategorize etme veya bulut tabanlı bir veritabanı (Firebase veya Supabase gibi) ile senkronize etme özelliklerini ekleyerek uygulamanızı daha ileri bir seviyeye taşıyabilirsiniz.
Yasal Uyarı: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanacağınız uygulamalarda, veri güvenliği, girdi doğrulama ve kullanıcı yetkilendirme gibi süreçlerin eksiksiz olduğundan emin olunuz. Yazılımcı, kodun yanlış kullanımı veya güvenlik açıklarından doğabilecek zararlardan sorumlu değildir.


Yorumlar (0)
Yorum Yaz