Türkçe

React Hata Sınırları ile zarif hata yönetimi uygulayın, uygulama çökmelerini önleyin ve kullanıcı deneyimini geliştirin. En iyi uygulamaları ve örnekleri keşfedin.

React Hata Sınırları (Error Boundaries): Sağlam Hata Yönetimi İçin Kapsamlı Bir Rehber

Modern web geliştirme dünyasında, sorunsuz ve güvenilir bir kullanıcı deneyimi her şeyden önemlidir. Tek bir işlenmemiş hata, tüm bir React uygulamasını çökerterek kullanıcıları hayal kırıklığına uğratabilir ve potansiyel olarak değerli verilerin kaybolmasına neden olabilir. React Hata Sınırları, bu hataları zarif bir şekilde yönetmek, feci çökmeleri önlemek ve daha dayanıklı ve kullanıcı dostu bir deneyim sunmak için güçlü bir mekanizma sağlar. Bu rehber, React Hata Sınırları'na kapsamlı bir genel bakış sunarak amaçlarını, uygulanmasını, en iyi uygulamalarını ve gelişmiş tekniklerini kapsar.

React Hata Sınırları (Error Boundaries) Nedir?

Hata Sınırları, alt bileşen ağacının herhangi bir yerindeki JavaScript hatalarını yakalayan, bu hataları kaydeden ve çöken bileşen ağacı yerine bir yedek kullanıcı arayüzü (fallback UI) gösteren React bileşenleridir. Uygulamanın bir bölümündeki hataların tüm kullanıcı arayüzünü çökertmesini önleyen bir güvenlik ağı görevi görürler. React 16 ile tanıtılan Hata Sınırları, önceki daha az sağlam hata yönetimi mekanizmalarının yerini almıştır.

Hata Sınırlarını, React bileşenleri için `try...catch` blokları olarak düşünebilirsiniz. Ancak, `try...catch`'ten farklı olarak, bileşenler için çalışırlar ve uygulamanız genelinde hataları yönetmek için bildirimsel (declarative) ve yeniden kullanılabilir bir yol sağlarlar.

Neden Hata Sınırları Kullanmalıyız?

Hata Sınırları birkaç önemli avantaj sunar:

Bir Hata Sınırı Bileşeni Oluşturma

Bir Hata Sınırı bileşeni oluşturmak için, aşağıdaki yaşam döngüsü yöntemlerinden birini veya her ikisini birden uygulayan bir sınıf bileşeni (class component) tanımlamanız gerekir:

İşte temel bir Hata Sınırı bileşeni örneği:


class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Durumu güncelle, böylece bir sonraki render yedek arayüzü gösterir.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // Örnek "componentStack":
    //   in ComponentThatThrows (created by App)
    //   in App
    console.error("Yakalanan bir hata: ", error, info.componentStack);
    // Hatayı bir hata raporlama servisine de kaydedebilirsiniz
    // logErrorToMyService(error, info.componentStack);
  }

  render() {
    if (this.state.hasError) {
      // İstediğiniz özel bir yedek arayüzü render edebilirsiniz
      return 

Bir şeyler ters gitti.

; } return this.props.children; } }

Açıklama:

Hata Sınırlarını Kullanma

Bir Hata Sınırı kullanmak için, korumak istediğiniz bileşeni veya bileşenleri ErrorBoundary bileşeniyle sarmalamanız yeterlidir:



  


Eğer ComponentThatMightThrow bir hata fırlatırsa, ErrorBoundary hatayı yakalayacak, durumunu güncelleyecek ve yedek kullanıcı arayüzünü render edecektir. Uygulamanın geri kalanı normal şekilde çalışmaya devam edecektir.

Hata Sınırı Yerleşimi

Hata Sınırlarının yerleşimi, etkili hata yönetimi için çok önemlidir. Şu stratejileri göz önünde bulundurun:

Örnek:


function App() {
  return (
    
); }

Bu örnekte, uygulamanın her bir ana bölümü (Header, Sidebar, ContentArea, Footer) bir Hata Sınırı ile sarmalanmıştır. Bu, her bölümün hataları bağımsız olarak yönetmesine olanak tanır ve tek bir hatanın tüm uygulamayı etkilemesini önler.

Yedek Arayüzü (Fallback UI) Özelleştirme

Bir Hata Sınırı tarafından görüntülenen yedek arayüz bilgilendirici ve kullanıcı dostu olmalıdır. Şu yönergeleri göz önünde bulundurun:

Örnek:


class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Durumu güncelle, böylece bir sonraki render yedek arayüzü gösterir.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // Hatayı bir hata raporlama servisine de kaydedebilirsiniz
    console.error("Yakalanan bir hata: ", error, info.componentStack);
  }

  render() {
    if (this.state.hasError) {
      // İstediğiniz özel bir yedek arayüzü render edebilirsiniz
      return (
        

Eyvah! Bir şeyler ters gitti.

Üzgünüz, bu içeriği göstermeye çalışırken bir hata oluştu.

Lütfen sayfayı yenilemeyi deneyin veya sorun devam ederse destek ile iletişime geçin.

Destek ile İletişime Geç
); } return this.props.children; } }

Bu örnek, açık bir hata mesajı, önerilen çözümler ve sayfayı yenileme ve destekle iletişime geçme bağlantılarını içeren daha bilgilendirici bir yedek kullanıcı arayüzü görüntüler.

Farklı Hata Türlerini Yönetme

Hata Sınırları, render sırasında, yaşam döngüsü yöntemlerinde ve altlarındaki tüm ağacın constructor'larında meydana gelen hataları yakalar. Şunlar için hataları yakalamazlar *değildir*:

Bu tür hataları yönetmek için farklı teknikler kullanmanız gerekir.

Olay Yöneticileri (Event Handlers)

Olay yöneticilerinde meydana gelen hatalar için standart bir try...catch bloğu kullanın:


function MyComponent() {
  const handleClick = () => {
    try {
      // Hata fırlatabilecek kod
      throw new Error("Olay yöneticisinde bir şeyler ters gitti");
    } catch (error) {
      console.error("Olay yöneticisindeki hata: ", error);
      // Hatayı yönet (örn. bir hata mesajı göster)
      alert("Bir hata oluştu. Lütfen tekrar deneyin.");
    }
  };

  return ;
}

Asenkron Kod

Asenkron kodda meydana gelen hatalar için, asenkron fonksiyon içinde try...catch blokları kullanın:


function MyComponent() {
  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch("https://api.example.com/data");
        const data = await response.json();
        // Veriyi işle
        console.log(data);
      } catch (error) {
        console.error("Veri alınırken hata oluştu: ", error);
        // Hatayı yönet (örn. bir hata mesajı göster)
        alert("Veri alınamadı. Lütfen daha sonra tekrar deneyin.");
      }
    }

    fetchData();
  }, []);

  return 
Veri yükleniyor...
; }

Alternatif olarak, işlenmemiş promise reddetmeleri (unhandled promise rejections) için genel bir hata yönetimi mekanizması kullanabilirsiniz:


window.addEventListener('unhandledrejection', function(event) {
  console.error('İşlenmemiş reddetme (promise: ', event.promise, ', neden: ', event.reason, ');');
  // İsteğe bağlı olarak genel bir hata mesajı görüntüleyin veya hatayı bir servise kaydedin
  alert("Beklenmedik bir hata oluştu. Lütfen daha sonra tekrar deneyin.");
});

Gelişmiş Hata Sınırı Teknikleri

Hata Sınırını Sıfırlama

Bazı durumlarda, kullanıcıların Hata Sınırını sıfırlamasına ve hataya neden olan işlemi yeniden denemesine olanak tanımak isteyebilirsiniz. Bu, hatanın bir ağ sorunu gibi geçici bir sorundan kaynaklanması durumunda yararlı olabilir.

Bir Hata Sınırını sıfırlamak için, hata durumunu yönetmek ve bir sıfırlama işlevi sağlamak üzere Redux veya Context gibi bir durum yönetimi kütüphanesi kullanabilirsiniz. Alternatif olarak, Hata Sınırını yeniden monte etmeye (remount) zorlayarak daha basit bir yaklaşım kullanabilirsiniz.

Örnek (Yeniden Monte Etmeye Zorlama):


class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false, errorCount: 0, key: 0 };
  }

  static getDerivedStateFromError(error) {
    // Durumu güncelle, böylece bir sonraki render yedek arayüzü gösterir.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // Hatayı bir hata raporlama servisine de kaydedebilirsiniz
    console.error("Yakalanan bir hata: ", error, info.componentStack);
    this.setState(prevState => ({ errorCount: prevState.errorCount + 1 }));
  }

  resetError = () => {
      this.setState({hasError: false, key: this.state.key + 1})
  }

  render() {
    if (this.state.hasError) {
      // İstediğiniz özel bir yedek arayüzü render edebilirsiniz
      return (
        

Eyvah! Bir şeyler ters gitti.

Üzgünüz, bu içeriği göstermeye çalışırken bir hata oluştu.

); } return
{this.props.children}
; } }

Bu örnekte, sarmalayan div'e bir 'key' eklenmiştir. Anahtarı (key) değiştirmek, bileşenin yeniden monte edilmesini zorlar ve hata durumunu etkili bir şekilde temizler. `resetError` metodu, bileşenin `key` durumunu güncelleyerek bileşenin yeniden monte edilmesine ve alt bileşenlerini yeniden render etmesine neden olur.

Hata Sınırlarını Suspense ile Kullanma

React Suspense, bir bileşenin render edilmesini bir koşul karşılanana kadar (örn. veri çekilene kadar) "askıya almanıza" olanak tanır. Asenkron işlemler için daha sağlam bir hata yönetimi deneyimi sağlamak üzere Hata Sınırlarını Suspense ile birleştirebilirsiniz.


import React, { Suspense } from 'react';

function MyComponent() {
  return (
    
      Yükleniyor...
}> ); } function DataFetchingComponent() { const data = useData(); // Veriyi asenkron olarak çeken özel bir hook return
{data.value}
; }

Bu örnekte, DataFetchingComponent özel bir hook kullanarak veriyi asenkron olarak çeker. Suspense bileşeni, veri çekilirken bir yükleme göstergesi görüntüler. Veri çekme işlemi sırasında bir hata oluşursa, ErrorBoundary hatayı yakalayacak ve bir yedek kullanıcı arayüzü görüntüleyecektir.

React Hata Sınırları için En İyi Uygulamalar

Gerçek Dünya Örnekleri

İşte Hata Sınırlarının nasıl kullanılabileceğine dair birkaç gerçek dünya örneği:

Hata Sınırlarına Alternatifler

Hata Sınırları React'te hataları yönetmenin önerilen yolu olsa da, düşünebileceğiniz bazı alternatif yaklaşımlar vardır. Ancak, bu alternatiflerin uygulama çökmelerini önlemede ve sorunsuz bir kullanıcı deneyimi sağlamada Hata Sınırları kadar etkili olmayabileceğini unutmayın.

Sonuç olarak, Hata Sınırları React'te hata yönetimine sağlam ve standartlaştırılmış bir yaklaşım sunar, bu da onları çoğu kullanım durumu için tercih edilen seçenek haline getirir.

Sonuç

React Hata Sınırları, sağlam ve kullanıcı dostu React uygulamaları oluşturmak için önemli bir araçtır. Hataları yakalayarak ve yedek kullanıcı arayüzleri görüntüleyerek uygulama çökmelerini önler, kullanıcı deneyimini iyileştirir ve hata ayıklamayı basitleştirir. Bu rehberde özetlenen en iyi uygulamaları takip ederek, Hata Sınırlarını uygulamalarınızda etkili bir şekilde uygulayabilir ve dünya genelindeki kullanıcılar için daha dayanıklı ve güvenilir bir kullanıcı deneyimi yaratabilirsiniz.