
A React 16 előtti verzióiban nem volt lehetőség arra, hogy a komponenseken belüli hibákat szépen kezeljük. Erre a React a Hibahatárok, angolul Error Boundaries bevezetésével hozta a megoldást. Ha nem tudod kimondani akkor használhatod kedvencemet az Error Bandi-t is :).
Az ide vonatkozó hivatalos link: https://hu.reactjs.org/docs/error-boundaries.html
Saját hibakezelő komponens
Egy ilyen hibakezelő komponenst minden olyan komponens köré lehet tenni, amin belül hibát szeretnék kezelni. Tehát hasonlóan, mint a Scroll komponensnek, ennek is lehetnek gyerekei (children).
Ahhoz, hogy ezt használni lehessen, kell csinálni egy class komponenst. Én csinálok neki egy könyvtárat és komponens fájlt is:

Aztán a komponens váza így néz ki a programkódban:
import React from "react";
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
};
}
render() {}
}
export default ErrorBoundary;
A constructor és a super is megkapta paraméterként a props-ot. Aztán a state-en belül megadtunk egy hasError tulajdonságot false értékkel.
Szóval most már ezt az ErrorBoundary komponenst fel tudjuk arra használni, hogy például elkapja a TerminatorList komponensen belül bekövetkező hibákat. A következő kérdés, hogy…
Hogyan kell a hibákat kezelni?
render() {
if (this.state.hasError) {
return <h1>Hoppá! Itt valami nem jó.</h1>;
}
return this.props.children;
}
A render() metódus törzsében egyszerűen megvizsgáljuk, hogy a state-ben tárolt hasError tulajdonság igazzá vált-e. Ha igen, akkor valami gáz van és a felhasználó arcába tolunk egy hibaüzenetet.
Ellenkező esetben pedig szépen visszaadjuk a children objektumot, vagyis azokat a komponenseket, amiket a hibakezelő komponens nyitó és záró tag-e közre fogott.
Ez eddig okés, de mi fogja nekünk átállítani a hasError értékét true-ra? A React 16-os verziójától kezdve bevezetett egy új életciklus metódust. Ez pedig a componentDidCatch(), ami nagyjából a JavaScript try-catch blokkjának felel meg.
componentDidCatch(error, info) {
this.setState({ hasError: true });
}
A metódusnak több paramétere is van és sok szép dolgot csinálhat. Nálunk most az egyszerűség kedvéért szimplán igazra állítja a hasError értékét.
Használathoz először is importálom az App.js fájlban:
import ErrorBoundary from "./components/error-boundary/error-boundary.component";
Aztán a kezelendő komponens köré kell rakni:
<Scroll>
<ErrorBoundary>
<TerminatorList models={filteredModels} />
</ErrorBoundary>
</Scroll>
Ha megnézzük a böngészőt, akkor sehol egy hiba. Valamit szándékosan hibára kellene futtani a TerminatorList komponensen belül. Ugyanis, ha azon belül hiba történik, akkor ezt az Error Bandi elkapja és kezelni fogja.
Hibakezelés próba
Én most akkor elrontom a TerminatorList komponenst:
const TerminatorList = ({ models }) => {
if (true) {
throw new Error("Hiba!");
}
return (
Most már a böngészőben is látszik, hogy valami nem stimmel, mert megjelenik a hibaüzenetünk:

Azt hiszem a React 17 előtti verzió esetében még a böngészőben is ahhoz hasonló hiba jelent meg, mint amiről a konzol is panaszkodik:

Azt akarja a tudtunkra adni, hogy valami hiba van a TerminatorList komponensen belül és a React megpróbálja újra felépíteni a komponens fát az Error Bandi segítségével.
Törlöm a szándékos hibát a kódból, mert ezt csak tesztelési célból tettem bele.
És ezzel végül is teljessé tettük első igazi React alkalmazásunkat, ami szépen működik és képes kezelni a hibákat is.
Az alkalmazás modernizálása Hook-ok használatával
Mielőtt még véget érne a React gyorstalpaló bejegyzés sorozat, az alkalmazást modernizálni fogjuk. Alkalmazásunkat átírjuk egy kissé és az eddig használt osztály komponenseket Hook-okra fogjuk lecserélni. Ugyanis a jövő irányvonala a Hook-ok használata. Hogy mik is azok a Hook-ok és hogyan kell „régi” class komponenseinket Hook-okra, azt a következő bejegyzésből megtudhatod.