Visaptveroša rokasgrāmata par JavaScript kļūdu robežu ieviešanu React, lai nodrošinātu stabilu kļūdu apstrādi un elegantu UI degradāciju.
JavaScript kļūdu robeža: React kļūdu apstrādes ieviešanas rokasgrāmata
React izstrādes pasaulē neparedzētas kļūdas var radīt nepatīkamu lietotāja pieredzi un lietojumprogrammas nestabilitāti. Labi definēta kļūdu apstrādes stratēģija ir būtiska, lai veidotu stabilas un uzticamas lietojumprogrammas. React kļūdu robežas (Error Boundaries) nodrošina jaudīgu mehānismu, lai eleganti apstrādātu kļūdas, kas rodas jūsu komponentu kokā, novēršot visas lietojumprogrammas avāriju un ļaujot parādīt rezerves lietotāja saskarni (fallback UI).
Kas ir kļūdu robeža?
Kļūdu robeža ir React komponents, kas uztver JavaScript kļūdas jebkurā vietā savā bērnu komponentu kokā, reģistrē šīs kļūdas un parāda rezerves lietotāja saskarni, nevis to komponentu koku, kurš avarēja. Kļūdu robežas uztver kļūdas renderēšanas laikā, dzīves cikla metodēs un konstruktoros visā zemāk esošajā kokā.
Uztveriet kļūdu robežu kā try...catch
bloku React komponentiem. Tāpat kā try...catch
bloks ļauj apstrādāt izņēmumus sinhronā JavaScript kodā, kļūdu robeža ļauj apstrādāt kļūdas, kas rodas jūsu React komponentu renderēšanas laikā.
Svarīga piezīme: Kļūdu robežas neuztver kļūdas, kas rodas:
- Notikumu apstrādātājos (vairāk uzziniet nākamajās sadaļās)
- Asinhronā kodā (piem.,
setTimeout
vairequestAnimationFrame
atzvanos) - Servera puses renderēšanā
- Pašā kļūdu robežas komponentā (nevis tā bērnos)
Kāpēc izmantot kļūdu robežas?
Kļūdu robežu izmantošana sniedz vairākas būtiskas priekšrocības:
- Uzlabota lietotāja pieredze: Tā vietā, lai rādītu baltu ekrānu vai nesaprotamu kļūdas paziņojumu, jūs varat parādīt lietotājam draudzīgu rezerves saskarni, informējot lietotāju, ka kaut kas nogāja greizi, un, iespējams, piedāvājot veidu, kā atgūties (piem., pārlādējot lapu vai pārejot uz citu sadaļu).
- Lietojumprogrammas stabilitāte: Kļūdu robežas novērš, ka kļūdas vienā lietojumprogrammas daļā izraisa visas lietojumprogrammas avāriju. Tas ir īpaši svarīgi sarežģītām lietojumprogrammām ar daudziem savstarpēji saistītiem komponentiem.
- Centralizēta kļūdu apstrāde: Kļūdu robežas nodrošina centralizētu vietu kļūdu reģistrēšanai un problēmu pamatcēloņa noteikšanai. Tas vienkāršo atkļūdošanu un uzturēšanu.
- Eleganta degradācija: Jūs varat stratēģiski izvietot kļūdu robežas ap dažādām lietojumprogrammas daļām, lai nodrošinātu, ka pat tad, ja daži komponenti neizdodas, pārējā lietojumprogramma paliek funkcionāla. Tas ļauj veikt elegantu degradāciju kļūdu gadījumā.
Kļūdu robežu ieviešana React
Lai izveidotu kļūdu robežu, jums ir jādefinē klases komponents, kas ievieš vienu (vai abas) no šīm dzīves cikla metodēm:
static getDerivedStateFromError(error)
: Šī dzīves cikla metode tiek izsaukta pēc tam, kad pēcnācēja komponents ir izmetis kļūdu. Tā saņem izmesto kļūdu kā argumentu, un tai ir jāatgriež vērtība, lai atjauninātu komponenta stāvokli, norādot, ka ir notikusi kļūda (piem., iestatothasError
karodziņu uztrue
).componentDidCatch(error, info)
: Šī dzīves cikla metode tiek izsaukta pēc tam, kad pēcnācēja komponents ir izmetis kļūdu. Tā saņem izmesto kļūdu kā argumentu, kā arīinfo
objektu, kas satur informāciju par to, kurš komponents izmeta kļūdu. Jūs varat izmantot šo metodi, lai reģistrētu kļūdu tādā servisā kā Sentry vai Bugsnag.
Šeit ir pamata piemērs kļūdu robežas komponentam:
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
error: null,
errorInfo: null
};
}
static getDerivedStateFromError(error) {
// Atjaunina stāvokli, lai nākamajā renderēšanā parādītu rezerves UI.
return {
hasError: true,
error: error
};
}
componentDidCatch(error, info) {
// "componentStack" piemērs:
// in ComponentThatThrows (created by App)
// in MyErrorBoundary (created by App)
// in div (created by App)
// in App
console.error("Uztverta kļūda:", error, info);
this.setState({
errorInfo: info.componentStack
});
// Jūs varat arī reģistrēt kļūdu kļūdu ziņošanas servisā
//logErrorToMyService(error, info.componentStack);
}
render() {
if (this.state.hasError) {
// Jūs varat renderēt jebkuru pielāgotu rezerves UI
return (
<div>
<h2>Kaut kas nogāja greizi.</h2>
<p>Kļūda: {this.state.error ? this.state.error.message : "Notika nezināma kļūda."}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.errorInfo && this.state.errorInfo}
</details>
</div>
);
}
return this.props.children;
}
}
Lai izmantotu kļūdu robežu, vienkārši ietiniet komponentu koku, kuru vēlaties aizsargāt:
<ErrorBoundary>
<MyComponentThatMightThrow/>
</ErrorBoundary>
Praktiski kļūdu robežu izmantošanas piemēri
Apskatīsim dažus praktiskus scenārijus, kuros kļūdu robežas var būt īpaši noderīgas:
1. API kļūdu apstrāde
Iegūstot datus no API, kļūdas var rasties tīkla problēmu, servera problēmu vai nederīgu datu dēļ. Jūs varat ietīt komponentu, kas iegūst un attēlo datus, ar kļūdu robežu, lai eleganti apstrādātu šīs kļūdas.
function UserProfile() {
const [user, setUser] = React.useState(null);
const [isLoading, setIsLoading] = React.useState(true);
React.useEffect(() => {
async function fetchData() {
try {
const response = await fetch('/api/user');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setUser(data);
} catch (error) {
// Kļūdu uztvers ErrorBoundary
throw error;
} finally {
setIsLoading(false);
}
}
fetchData();
}, []);
if (isLoading) {
return <p>Ielādē lietotāja profilu...</p>;
}
if (!user) {
return <p>Lietotāja dati nav pieejami.</p>;
}
return (
<div>
<h2>{user.name}</h2>
<p>Email: {user.email}</p>
</div>
);
}
function App() {
return (
<ErrorBoundary>
<UserProfile />
</ErrorBoundary>
);
}
Šajā piemērā, ja API izsaukums neizdodas vai atgriež kļūdu, kļūdu robeža uztvers kļūdu un parādīs rezerves UI (definētu kļūdu robežas render
metodē). Tas novērš visas lietojumprogrammas avāriju un sniedz lietotājam informatīvāku ziņojumu. Jūs varētu paplašināt rezerves UI, lai nodrošinātu iespēju atkārtot pieprasījumu.
2. Trešo pušu bibliotēku kļūdu apstrāde
Lietojot trešo pušu bibliotēkas, ir iespējams, ka tās var izmest neparedzētas kļūdas. Komponentu, kas izmanto šīs bibliotēkas, ietīšana ar kļūdu robežām var palīdzēt eleganti apstrādāt šīs kļūdas.
Apsveriet hipotētisku diagrammu bibliotēku, kas laiku pa laikam izmet kļūdas datu neatbilstību vai citu problēmu dēļ. Jūs varētu ietīt diagrammu komponentu šādi:
function MyChartComponent() {
try {
// Renderē diagrammu, izmantojot trešās puses bibliotēku
return <Chart data={data} />;
} catch (error) {
// Šis catch bloks nebūs efektīvs React komponenta dzīves cikla kļūdām
// Tas galvenokārt paredzēts sinhronām kļūdām šajā konkrētajā funkcijā.
console.error("Kļūda, renderējot diagrammu:", error);
// Apsveriet iespēju izmest kļūdu, lai to uztvertu ErrorBoundary
throw error; // Kļūdas atkārtota izmešana
}
}
function App() {
return (
<ErrorBoundary>
<MyChartComponent />
</ErrorBoundary>
);
}
Ja Chart
komponents izmet kļūdu, kļūdu robeža to uztvers un parādīs rezerves UI. Ņemiet vērā, ka try/catch bloks MyChartComponent ietvaros uztvers tikai kļūdas sinhronajā funkcijā, nevis komponenta dzīves ciklā. Tāpēc kļūdu robeža šeit ir kritiski svarīga.
3. Renderēšanas kļūdu apstrāde
Kļūdas var rasties renderēšanas procesā nederīgu datu, nepareizu prop tipu vai citu problēmu dēļ. Kļūdu robežas var uztvert šīs kļūdas un novērst lietojumprogrammas avāriju.
function DisplayName({ name }) {
if (typeof name !== 'string') {
throw new Error('Vārdam jābūt virknei');
}
return <h2>Sveiki, {name}!</h2>;
}
function App() {
return (
<ErrorBoundary>
<DisplayName name={123} /> <!-- Nepareizs prop tips -->
</ErrorBoundary>
);
}
Šajā piemērā DisplayName
komponents sagaida, ka name
prop būs virkne. Ja tā vietā tiek nodots skaitlis, tiks izmesta kļūda, un kļūdu robeža to uztvers un parādīs rezerves UI.
Kļūdu robežas un notikumu apstrādātāji
Kā minēts iepriekš, kļūdu robežas neuztver kļūdas, kas rodas notikumu apstrādātājos. Tas ir tāpēc, ka notikumu apstrādātāji parasti ir asinhroni, un kļūdu robežas uztver tikai kļūdas, kas rodas renderēšanas laikā, dzīves cikla metodēs un konstruktoros.
Lai apstrādātu kļūdas notikumu apstrādātājos, jums ir jāizmanto tradicionālais try...catch
bloks notikumu apstrādātāja funkcijā.
function MyComponent() {
const handleClick = () => {
try {
// Kods, kas varētu izmest kļūdu
throw new Error('Notikumu apstrādātājā radās kļūda');
} catch (error) {
console.error('Notikumu apstrādātājā uztverta kļūda:', error);
// Apstrādājiet kļūdu (piem., parādiet kļūdas ziņojumu lietotājam)
}
};
return <button onClick={handleClick}>Noklikšķini</button>;
}
Globālā kļūdu apstrāde
Lai gan kļūdu robežas ir lieliskas kļūdu apstrādei React komponentu kokā, tās neaptver visus iespējamos kļūdu scenārijus. Piemēram, tās neuztver kļūdas, kas rodas ārpus React komponentiem, piemēram, kļūdas globālos notikumu klausītājos vai kodā, kas tiek izpildīts pirms React inicializēšanas.
Lai apstrādātu šāda veida kļūdas, varat izmantot window.onerror
notikumu apstrādātāju.
window.onerror = function(message, source, lineno, colno, error) {
console.error('Globālais kļūdu apstrādātājs:', message, source, lineno, colno, error);
// Reģistrējiet kļūdu tādā servisā kā Sentry vai Bugsnag
// Parādiet globālu kļūdas ziņojumu lietotājam (pēc izvēles)
return true; // Novērš noklusējuma kļūdu apstrādes darbību
};
Svarīgi: Atgriežot true
no window.onerror
notikumu apstrādātāja, tiek novērsta pārlūkprogrammas noklusējuma kļūdas ziņojuma parādīšana. Tomēr ņemiet vērā lietotāja pieredzi; ja jūs nomācat noklusējuma ziņojumu, nodrošiniet skaidru un informatīvu alternatīvu.
Labākās prakses kļūdu robežu izmantošanai
Šeit ir dažas labākās prakses, kas jāpatur prātā, lietojot kļūdu robežas:
- Izvietojiet kļūdu robežas stratēģiski: Ietiniet dažādas lietojumprogrammas daļas ar kļūdu robežām, lai izolētu kļūdas un novērstu to kaskadēšanu. Apsveriet iespēju ietīt veselus maršrutus vai lielas UI sadaļas.
- Nodrošiniet informatīvu rezerves UI: Rezerves UI vajadzētu informēt lietotāju, ka ir notikusi kļūda, un, iespējams, piedāvāt veidu, kā atgūties. Izvairieties no vispārīgu kļūdu ziņojumu, piemēram, "Kaut kas nogāja greizi.", rādīšanas.
- Reģistrējiet kļūdas: Izmantojiet
componentDidCatch
dzīves cikla metodi, lai reģistrētu kļūdas tādā servisā kā Sentry vai Bugsnag. Tas palīdzēs jums atrast problēmu pamatcēloni un uzlabot jūsu lietojumprogrammas stabilitāti. - Neizmantojiet kļūdu robežas paredzamām kļūdām: Kļūdu robežas ir paredzētas neparedzētu kļūdu apstrādei. Paredzamām kļūdām (piem., validācijas kļūdas, API kļūdas) izmantojiet specifiskākus kļūdu apstrādes mehānismus, piemēram,
try...catch
blokus vai pielāgotus kļūdu apstrādes komponentus. - Apsveriet vairākus kļūdu robežu līmeņus: Jūs varat ligzdot kļūdu robežas, lai nodrošinātu dažādus kļūdu apstrādes līmeņus. Piemēram, jums varētu būt globāla kļūdu robeža, kas uztver jebkādas neapstrādātas kļūdas un parāda vispārīgu kļūdas ziņojumu, un specifiskākas kļūdu robežas, kas uztver kļūdas konkrētos komponentos un parāda detalizētākus kļūdu ziņojumus.
- Neaizmirstiet par servera puses renderēšanu: Ja izmantojat servera puses renderēšanu, jums būs jāapstrādā kļūdas arī serverī. Kļūdu robežas darbojas serverī, bet jums var būt nepieciešami papildu kļūdu apstrādes mehānismi, lai uztvertu kļūdas, kas rodas sākotnējās renderēšanas laikā.
Papildu kļūdu robežu tehnikas
1. Render Prop izmantošana
Tā vietā, lai renderētu statisku rezerves UI, jūs varat izmantot render prop, lai nodrošinātu lielāku elastību kļūdu apstrādē. Render prop ir funkcijas prop, ko komponents izmanto, lai kaut ko renderētu.
class ErrorBoundary extends React.Component {
// ... (tāpat kā iepriekš)
render() {
if (this.state.hasError) {
// Izmantojiet render prop, lai renderētu rezerves UI
return this.props.fallbackRender(this.state.error, this.state.errorInfo);
}
return this.props.children;
}
}
function App() {
return (
<ErrorBoundary fallbackRender={(error, errorInfo) => (
<div>
<h2>Kaut kas nogāja greizi!</h2>
<p>Kļūda: {error.message}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{errorInfo.componentStack}
</details>
</div>
)}>
<MyComponentThatMightThrow/>
</ErrorBoundary>
);
}
Tas ļauj jums pielāgot rezerves UI katrai kļūdu robežai atsevišķi. fallbackRender
prop saņem kļūdu un kļūdas informāciju kā argumentus, ļaujot jums parādīt specifiskākus kļūdu ziņojumus vai veikt citas darbības, pamatojoties uz kļūdu.
2. Kļūdu robeža kā augstākas kārtas komponents (HOC)
Jūs varat izveidot augstākas kārtas komponentu (HOC), kas ietin citu komponentu ar kļūdu robežu. Tas var būt noderīgi, lai piemērotu kļūdu robežas vairākiem komponentiem, neatkārtojot to pašu kodu.
function withErrorBoundary(WrappedComponent) {
return class WithErrorBoundary extends React.Component {
render() {
return (
<ErrorBoundary>
<WrappedComponent {...this.props} />
</ErrorBoundary>
);
}
};
}
// Lietošana:
const MyComponentWithErrorHandling = withErrorBoundary(MyComponentThatMightThrow);
Funkcija withErrorBoundary
pieņem komponentu kā argumentu un atgriež jaunu komponentu, kas ietin sākotnējo komponentu ar kļūdu robežu. Tas ļauj jums viegli pievienot kļūdu apstrādi jebkuram komponentam jūsu lietojumprogrammā.
Kļūdu robežu testēšana
Ir svarīgi testēt jūsu kļūdu robežas, lai nodrošinātu, ka tās darbojas pareizi. Jūs varat izmantot testēšanas bibliotēkas, piemēram, Jest un React Testing Library, lai testētu savas kļūdu robežas.
Šeit ir piemērs, kā testēt kļūdu robežu, izmantojot React Testing Library:
import { render, screen, fireEvent } from '@testing-library/react';
import ErrorBoundary from './ErrorBoundary';
function ComponentThatThrows() {
throw new Error('Šis komponents izmet kļūdu');
}
test('renderē rezerves UI, kad tiek izmesta kļūda', () => {
render(
<ErrorBoundary>
<ComponentThatThrows />
</ErrorBoundary>
);
expect(screen.getByText('Kaut kas nogāja greizi.')).toBeInTheDocument();
});
Šis tests renderē ComponentThatThrows
komponentu, kas izmet kļūdu. Pēc tam tests apgalvo, ka tiek parādīts kļūdu robežas renderētais rezerves UI.
Kļūdu robežas un servera komponenti (React 18+)
Līdz ar servera komponentu ieviešanu React 18 un jaunākās versijās, kļūdu robežām joprojām ir būtiska loma kļūdu apstrādē. Servera komponenti tiek izpildīti serverī un nosūta klientam tikai renderēto izvadi. Lai gan pamatprincipi paliek nemainīgi, ir dažas nianses, kas jāņem vērā:
- Servera puses kļūdu reģistrēšana: Pārliecinieties, ka reģistrējat kļūdas, kas rodas servera komponentos, serverī. Tas var ietvert servera puses reģistrēšanas ietvara izmantošanu vai kļūdu sūtīšanu uz kļūdu izsekošanas servisu.
- Klienta puses rezerve: Pat ja servera komponenti tiek renderēti serverī, jums joprojām ir jānodrošina klienta puses rezerves UI kļūdu gadījumā. Tas nodrošina, ka lietotājam ir konsekventa pieredze, pat ja serveris nespēj renderēt komponentu.
- Straumēšanas SSR: Izmantojot straumēšanas servera puses renderēšanu (SSR), straumēšanas procesa laikā var rasties kļūdas. Kļūdu robežas var palīdzēt jums eleganti apstrādāt šīs kļūdas, renderējot rezerves UI ietekmētajai straumei.
Kļūdu apstrāde servera komponentos ir attīstības stadijā, tāpēc ir svarīgi sekot līdzi jaunākajām labākajām praksēm un ieteikumiem.
Biežākās kļūdas, no kurām izvairīties
- Pārmērīga paļaušanās uz kļūdu robežām: Neizmantojiet kļūdu robežas kā aizstājēju pareizai kļūdu apstrādei jūsu komponentos. Vienmēr centieties rakstīt stabilu un uzticamu kodu, kas eleganti apstrādā kļūdas.
- Kļūdu ignorēšana: Pārliecinieties, ka reģistrējat kļūdas, ko uztver kļūdu robežas, lai varētu atrast problēmu pamatcēloni. Ne tikai parādiet rezerves UI un ignorējiet kļūdu.
- Kļūdu robežu izmantošana validācijas kļūdām: Kļūdu robežas nav pareizais rīks validācijas kļūdu apstrādei. Tā vietā izmantojiet specifiskākas validācijas tehnikas.
- Kļūdu robežu netestēšana: Testējiet savas kļūdu robežas, lai pārliecinātos, ka tās darbojas pareizi.
Noslēgums
Kļūdu robežas ir jaudīgs rīks stabilu un uzticamu React lietojumprogrammu veidošanai. Izprotot, kā efektīvi ieviest un izmantot kļūdu robežas, jūs varat uzlabot lietotāja pieredzi, novērst lietojumprogrammu avārijas un vienkāršot atkļūdošanu. Atcerieties stratēģiski izvietot kļūdu robežas, nodrošināt informatīvu rezerves UI, reģistrēt kļūdas un rūpīgi testēt savas kļūdu robežas.
Ievērojot šajā rokasgrāmatā sniegtos norādījumus un labākās prakses, jūs varat nodrošināt, ka jūsu React lietojumprogrammas ir noturīgas pret kļūdām un sniedz pozitīvu pieredzi jūsu lietotājiem.