Skip to content
Kezdőlap » Hibakezelés a komponenseken belül – ReactJS gyorstalpaló 9.

Hibakezelés a komponenseken belül – ReactJS gyorstalpaló 9.

Hibakezelés a komponenseken belül

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:

Hibakezelés a komponenseken belül

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:

Hibakezelés a komponenseken belül

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.