Xəta Sərhədləri
These docs are old and won’t be updated. Go to react.dev for the new React docs.
These new documentation pages teach modern React:
Keçmişdə, komponent daxilində baş verən Javascript xətaları, React-in daxili vəziyyətini korlayıb, sonrakı renderlərdə kriptik xətalar göstərirdi. Bu xətaların həmişə applikasiya kodunda əvvəlki xətalara görə baş verməyinə baxmayaraq, React bu xətaların komponent daxilində idarəsi üçün və bu xətalardan bərpa olunmaq üçün heç bir mexanizm təmin etmirdi.
Xəta Sərhədlərinin Təqdim Edilməsi
UI-ın bir hissəsində baş verən Javascript xətası bütün applikasiyanı sındırmamalıdır. Bu problemin React-də həll olunması üçün, React 16 “xəta sərhədi” adında yeni bir konsepsiya təqdim edir.
Xəta sərhədləri uşaq komponent ağacında baş verən Javascript xətaları tutan, bu xətaları qeydiyyata alan və xəta olduqda fallback UI göstərən bir React komponentidir. Xəta sərhədləri render zamanı, lifecycle metodlarında, və bütün altında olan ağacdakı konstruktorlarda baş verən xətaları tutur.
Qeyd
Xəta sərhədləri aşağıda baş verən xətaları tutmur:
- Hadisə işləyicilərində (daha ətraflı)
- Asinxron kod (məsələn
setTimeout
və yarequestAnimationFrame
callback-ləri)- Serverdə render edilməsi zamanı
- Xəta sərhədinin daxilində atılan xətalar (uşaqda atılmağın yerinə)
Sinif komponenti göstərilən static getDerivedStateFromError()
və ya componentDidCatch()
lifecycle metodlarının birini (və ya hər ikisini) tətbiq etdikdə xəta sərhədinə çevrilir. static getDerivedStateFromError()
funksiyasını xəta atıldıqdan sonra fallback UI render etmək üçün işlədin. componentDidCatch()
funksiyasını xətaları qeydiyyata almaq üçün işlədin.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) { // Gələn renderdə UI göstərmək üçün state-i yeniləyin. return { hasError: true }; }
componentDidCatch(error, errorInfo) { // Siz həmçinin xətaları, xəta hesabat servislərində qeydiyyata ala bilərsiniz logErrorToMyService(error, errorInfo); }
render() {
if (this.state.hasError) { // Siz hər hansı bir fallback UI render edə bilərsiniz return <h1>Bir şey yalnış getdi.</h1>; }
return this.props.children;
}
}
Sonra siz bunu normal komponent kimi işlədə bilərsiniz:
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
Xəta sərhədləri komponentlər üçün Javascript-in catch {}
bloku kimi işləyirlər. Yalnız sinif komponentləri xəta sərhədləri ola bilər. Praktikada, bir çox zaman, siz xəta sərhədi komponentini bir dəfə tətbiq edib bütün applikasiya zamanı işlətmək istəyərsiniz.
Qeyd edək ki, xəta sərhədləri yalnız altındakı ağacda olan komponentlərin xətalarını tuta bilir. Xəta sərhədi daxilində baş verən xətanı tuta bilmir. Əgər xəta sərhədin xəta mesajını render edə bilmirsə, xəta bu komponentin yuxarısında olan ən yaxın xəta sərhədinə yayılacaq. Javascriptin catch {} funksiyasıda bunun kimi işləyir.
Canlı Demo
React 16-da xəta sərhədinin yaranması və işlənməsi misalına baxın.
Xəta sərhədlərinin zənginliyi / əhatəsi sizdən asılıdır. Siz ən yuxarıda olan route komponentlərini əhatə edib, server tərəfində işlənilən freymvorklardakı kimi, “Bir şey yalnış getdi” mesajını istifadəçiyə göstərə bilərsiniz. Siz həmçinin fərdi vidcetlərini xəta sərhədləri ilə əhatə edib xətaların bütün applikasiyanı sındırmasından qoruya bilərsiniz.
Tutulmamış Xətalar üçün Yeni Davranış
Bu dəyişikliyin vacib bir təsiri var. React 16-dan başlayaraq, xəta sərhədində tutulmayan xətalar, React komponent ağacının bütünlüklə DOM-dan çıxarılmasına səbəb olacaq.
Biz bu qərarı müzakirə etdik və bizim təcrübəmizdən korlanmış UI-ı yerində saxlamaq, bu UI-ı bütün silməkdən daha pisdir. Məsələn, Messenger kimi bir məhsulda, sınmış UI-ı göstərmək, kiminsə yalnış adama mesaj göndərməsinə səbəb ola bilər. Eyniliklə, ödəmə applikasiyasının yalnız dəyər göstərməsi heç nə göstərməsindən daha pisdir.
Bu dəyişikliklə siz React 16-a miqrasiya etdikdə, sizin applikasiyanızda əvvəl fikir vermədiyiniz mövcud xətaların üstünü aça biləcəksiniz. Xəta sərhədlərini əlavə etməklə bir şey yalnış getdikdə daha yaxşı istifadəçi təcrübəsi yarada bilərsiniz.
Məsələn, Facebook Messenger sidebar-ı, məlumat panelini, chat yazılarını, və mesaj daxil etməsini ayrılıqda xəta sərhədləri ilə əhətə edir. Əgər hər hansı bir UI sahəsində bir komponent sınırsa, applikasiyanın qalanı interaktiv qalır.
Biz həmçinin sizin Javascript xəta servislərindən (və ya özünüz düzəldin) istifadə etməyi tövsiyə edirik. Bu servislər ilə production-da baş verən xətaları tapıb, bu xətaları düzədə bilərsiniz.
Komponent Stek İzləri
React 16 render zamanı baş verən bütün xətaları, applikasiya təsadüfən bu xətaları udsa belə, development zamanı brauzerin konsoluna yazır. Xəta mesajı və Javascript stekindən əlavə, həmçinin React 16 həmçinin komponent stek izlərini göstərir. İndi siz xətanın komponent ağacında dəqiq harada baş verdiyini görə bilərsiniz:
Siz komponentin stek izində fayl adlarını və sətir nömrələrini də görə bilərsiniz. Bu Create React App layihələrində birbaşa işləyir:
Əgər siz Create React App istifadə etmirsinizsə, siz bu plugini əllə Babel konfiqurasiyasına əlavə edə bilərsiniz. Nəzərə alın ki, bu yalnız təkmilləşmə zamanı işlədilməli və produksiyada söndürülməlidir.
Qeyd
Komponent adları stek izlərində
Function.name
parametrindən asılıdır. Əgər siz bu parametri nativ formada dəstəkləməyən köhnə brauzerləri və cihazları dəstəkləyirsinizsə (məsələn IE 11),Function.name
polifilini (məsələnfunction.name-polyfill
) paketlənmiş applikasiyanıza əlavə edin. Alternativ olaraq, siz açıq şəkildədisplayName
parametrini bütün komponentlərdə təyin edə bilərsiniz.
Bəs try/catch?
try
/ catch
əladır amma yalnız imperativ kod ilə işləyir:
try {
showButton();
} catch (error) {
// ...
}
Lakin, React komponentlər deklarativdirlər və nəyin render olunacağını müəyyənləşdirirlər:
<Button />
Xəta sərhərləri React-in deklarativ təbiətini saxlayır və sizin gözlədiyiniz kimi davranırlar. Məsələn, əgər xəta, ağacın dərinliyində olan komponentin componentDidUpdate
funksiyasında setState
-ə görə baş versə belə, React yenədə xətanı ən yaxın xəta sərhədinə yayacaq.
Bəs Hadisə İşləyiciləri?
Xəta sərhədləri hadisə işləyicilərində baş verən xətaları tutmur.
React-ə hadisə işləyicilərində baş verən xətaların bərpası üçün, xəta sərhədlərindən istifadə etməsi lazım deyil. Render və lifecycle metodlarından fərqli olaraq, hadisə işləyiciləri render zamanı baş vermir. Bu səbəbdən, əgər bu işləyicilər xəta atırlarsa, React yenə də ekranda nə göstərəcəyini bilir.
Əgər sizə hadisə işləyicilərində yeni xətanı tutmaq lazımdırsa, normal Javascript try
/ catch
ifadəsindən istifadə edin:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { error: null };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
try { // Xəta atması üçün nəsə edin } catch (error) { this.setState({ error }); } }
render() {
if (this.state.error) { return <h1>Xəta tutuldu.</h1> } return <button onClick={this.handleClick}>Tıkla</button> }
}
Qeyd edək ki, yuxarıdakı nümunə normal Javascript davranışını göstərir və xəta sərhədindən istifadə etmir.
React 15-dən ad dəyişiklikləri
React 15 xəta sərhədlərini fərqli funksiya adı ilə çox məhdudiyyətli formada dəstəkləyirdi: unstable_handleError
. Bu funksiya artıq işləmir və siz React 16 betadan başlayaraq bunu componentDidCatch
ilə əvəz etməlisiniz.
Bu dəyişiklik üçün, biz kodunuzun avtomatik miqrasiyası üçün codemod təmin etmişik.