Horgok szabályai

A Horgok a React 16.8-as verziójában lettek hozzáadva. Osztályok létrehozása nélkül is lehetőséget kínálnak állapot, és más React funkciók használatához.

A Horgok JavaScript függvények, de használatukkor két szabályt be kell tarts. Szolgáltatunk egy linter plugint, ami ezen szabályok automatikus betartására kényszerít:

Horgokat csakis a legfelsőbb szinten hívj meg

Ne hívj meg Horgokat ciklusokban, feltételes ágakban, vagy egymásba ágyazott függvényekben. A Horgokat mindig a React függvényed legfelső szintjén hívd meg. Ennek a szabálynak a betartásával gondoskodsz róla, hogy a Horgok a komponens minden renderelésénél ugyanabban a sorrendben legyenek meghívva. Ez teszi lehetővé a React számára több useState és useEffect hívás esetén az állapot megőrzését. (Ha kíváncsi vagy, lentebb ezt részletesen is kifejtjük.)

Horgokat csakis React függvényekből hívj meg

Ne hívj meg Horgokat általános JavaScript függvényekből. Ehelyett:

  • ✅ Horgokat React függvénykomponensekből hívj meg.
  • ✅ Horgokat egyedi Horgokból hívj meg (erről többet fogunk tanulni a következő oldalon).

Ennek a szabálynak a betartásával gondoskodsz róla, hogy minden állapotteljes komponenslogika tisztán kiolvasható legyen a forráskódból.

ESLint Plugin

Kiadtunk egy ESLint plugint eslint-plugin-react-hooks néven, ami ezt a két szabályt segít betartani. Ha ki szeretnéd próbálni, így tudod hozzáadni a projektedhez:

Ezt a plugint a Create React App alapból tartalmazza.

npm install eslint-plugin-react-hooks --save-dev
// Az ESLint konfigurációd
{
  "plugins": [
    // ...
    "react-hooks"
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error", // Ellenőrzi a Horgok szabályainak betartását
    "react-hooks/exhaustive-deps": "warn" // Ellenőrzi a hatásfüggőségeket
  }
}

A saját Horgod írásához most továbbléphetsz a következő oldalra. Ezen az oldalon tovább magyarázzuk az érveléseinket ezen szabályok mellett.

Magyarázat

Ahogy korábban megtanultuk, egy komponensben egyszerre több Állapot és Hatás Horgot is használhatunk:

function Form() {
  // 1. Használd a név állapotváltozót
  const [name, setName] = useState('Mary');

  // 2. Használj egy hatást az űrlap megőrzésére
  useEffect(function persistForm() {
    localStorage.setItem('formData', name);
  });

  // 3. Használd a családi név állapotváltozót
  const [surname, setSurname] = useState('Poppins');

  // 4. Használj egy hatást a dokumentum címének frissítéséhez
  useEffect(function updateTitle() {
    document.title = name + ' ' + surname;
  });

  // ...
}

Szóval hogyan is tudja a React, hogy melyik állapothoz melyik useState hívás tartozik? A válasz, hogy a React a Horgok meghívásának sorrendjére hagyatkozik. A példánk azért működik, mert a Horgok meghívásának sorrendje minden renderelés során ugyanaz:

// ------------
// Első renderelés
// ------------
useState('Mary')           // 1. Inicializáld a név állapotváltozót 'Mary'-vel
useEffect(persistForm)     // 2. Adj hozzá egy hatást az űrlap megőrzéséért
useState('Poppins')        // 3. Inicializáld a családi név állapotváltozót 'Poppins'-szal
useEffect(updateTitle)     // 4. Adj hozzá egy hatást a cím frissítéséért

// -------------
// Második renderelés
// -------------
useState('Mary')           // 1. Olvasd ki a énv állapotváltozót (az argumentum ignorálva van)
useEffect(persistForm)     // 2. Cseréld le a hatást az űrlap megőrzéséért
useState('Poppins')        // 3. Olvasd ki a családi név állapotváltozót (az argumentum ignorálva van)
useEffect(updateTitle)     // 4. Cseréld ki a hatást a cím frissítéséért

// ...

Egészen addig, amíg a Horgok meghívása nem változik a renderelések között, a React asszociálni tudja a helyi állapotokat ezekkel. De mi történik, ha az egyik Horog meghívását (például a persistForm hatást) egy feltételbe tesszük?

  // 🔴 Ezzel megszegjük az első szabályt, mivel a Horgot egy feltételben használjuk
  if (name !== '') {
    useEffect(function persistForm() {
      localStorage.setItem('formData', name);
    });
  }

A name !== '' feltétel true az első rendereléskor, szóval lefuttatjuk a Horgot. Azonban a következő rendereléskor a felhasználó törölheti az űrlapot, ezzel false-ra állítva feltételt. Most, hogy a renderelés során kihagyjuk a Horog meghívását, a Horgok meghívásának sorrendje megváltozik:

useState('Mary')           // 1. Olvasd ki a énv állapotváltozót (az argumentum ignorálva van)
// useEffect(persistForm)  // 🔴 Ez a Horog ki lett hagyva!
useState('Poppins')        // 🔴 2 (de az előbb 3 volt). Nem tudja kiolvasni a családi név állapotváltozót
useEffect(updateTitle)     // 🔴 3 (de az előbb 4 volt). Nem tudja kicserélni a hatást

A React nem tudhatta, hogy mit adjon vissza a második useState Horog meghívásakor. A React arra számított, hogy a komponensben lévő második Horog meghívása a persistForm hatásnak felel meg, ahogyan az előző rendereléskor is, de most már nem ez a helyzet. Mostantól minden Horog meghívás a kihagyás után el van csúszva eggyel, ami hibákhoz vezet.

Ezért kell, hogy a Horgok csak a komponensünk legfelsőbb szintjén legyenek meghívva. Ha egy hatást feltételesen szeretnénk futtatni, vigyük át a feltételt a Horgon belülre:

  useEffect(function persistForm() {
    // 👍 Így már nem szegjük meg az első szabályt
    if (name !== '') {
      localStorage.setItem('formData', name);
    }
  });

Jegyezd meg, hogy ettől a problémától nem kell tartanod, ha használod a szolgáltatott lint szabályt. De most már azt is tudod, hogy miért működnek így a Horgok, és milyen hibákat előz meg a szabály.

Következő lépések

Végre, készen állunk saját Horgaid írásának tanulására! Az Egyedi Horgok lehetővé teszik a React által szolgáltatott Horgokat saját absztrakcióidba kombinálni, és állapotteljes logika újrafelhasználását különböző komponensek között.

Is this page useful?Az oldal szerkesztése