Horgok egy pillantásra

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 visszafelé kompatibilisek. Ez az oldal tapasztalt React felhasználóknak ad egy áttekintést a Horgokról. Ez egy gyorsütemű áttekintés. Ha összezavarodnál, keress egy ilyen sárga dobozt:

Részletes magyarázat

Olvasd el a Motiváció részt, hogy megértsd, miért is adjuk a Horgokat a Reacthez.

↑↑↑ Minden szekció egy ilyen sárga dobozzal végződik. Részletes magyarázatokat linkelnek.

📌 Állapot horog

Ez a példa egy számlálót renderel. A gombra kattintáskor növeli az értéket:

import React, { useState } from 'react';
function Example() {
  // Egy új állapot változó deklarálása, amit "count"-nak fogunk hívni  const [count, setCount] = useState(0);
  return (
    <div>
      <p>{count} alkalommal kattintottál</p>
      <button onClick={() => setCount(count + 1)}>
        Kattints rám
      </button>
    </div>
  );
}

Itt, a useState egy Horog (mindjárt arról is beszélünk, hogy ez mit is jelent). Egy függvénykomponensben hívjuk meg, hogy ahhoz állapotot tudjunk rendelni. A React az újrarenderelések között megőrzi ezt az állapot. A useState egy párt ad vissza: a jelenlegi állapotértéket, és egy függvényt, amivel azt frissíteni tudjuk. Ezt a függvényt meghívhatod egy eseménykezelőből, vagy máshonnan is. Hasonló az osztályokban megtalálható this.setState-hez, kivéve, hogy ez nem egyesíti a régi és az új állapotokat. (Az Állapot Horog használata fejezetben mutatni fogunk egy példát, ami összehasonlítja a useState-t és a this.state-t.)

A useState egyetlen argumentuma az állapot kezdeti értéke. A fenti példában ez 0, mert a számlálónk nullától indul. Jegyezd meg, hogy a this.state-től eltérően az állapot itt nem egy objektum — bár lehetne, ha azt szeretnéd. A kezdeti állapot argumentum csupán az első renderelés alkalmával van használva.

Több állapotváltozó deklarálása

Az Állapot Horgot többször is használhatod egy komponensen belül:

function ExampleWithManyStates() {
  // Deklarálj egyszerre több állapotváltozót!
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banán');
  const [todos, setTodos] = useState([{ text: 'Tanuld meg a Horgokat' }]);
  // ...
}

A tömb lebontó szintaxis lehetővé teszi számunkra különféle nevet adni a useState hívásakor a deklarált állapotváltozóknak. Ezek a nevek nem a useState API részei. Ehelyett a React feltételezi, hogy ha a useState-t többször is meghívod, akkor ezt minden renderelés során ugyanabban a sorrendben teszed. Később vissza fogunk térni arra, hogy ez miért működik, és mikor igazán hasznos.

De mi is egy Horog igazából?

A horgok függvények, amik “beleakaszkodnak” a React állapot és életciklus funkciókba függvénykomponensekből. A horgok nem működnek osztálykomponensekben — a React használatát teszik lehetővé, osztályok nélkül. (Meglévő komponensek átírását egyik napról a másikra nem ajánljuk, de új komponensekben elkezdhetsz Horgokat használni, ha szeretnéd.)

A React biztosít néhány beépített Horgot, mint a useState. Saját Horgokat is készíthetsz, ha állapotteljes viselkedést szeretnél különböző komponensek között megosztani. Először nézzük a beépített Horgokat.

Részletes magyarázat

Az Állapot Horogról az annak dedikált oldalon többet tanulhatsz: Állapot Horog használata.

⚡️ Hatás Horog

Valószínűleg hajtottál már végre adatlehívást, feliratkozást, vagy manuális DOM változást React komponensekből. Ezeket a műveleteket “mellékhatásoknak” (vagy röviden csak “hatásoknak”) hívjuk, mert más komponensekre is kihatással lehetnek, és renderelés közben nem elvégezhető műveletek.

A Hatás Horog, useEffect, mellékhatások elvégzését teszi lehetővé függvénykomponensekből. Ugyanazt a célt szolgálja mint a React osztálybeli componentDidMount, componentDidUpdate, és componentWillUnmount, de egy egyszerű API-be sűrítve. (A Hatás Horog használata fejezetben mutatni fogunk egy példát, ami összehasonlítja a useEffect-et ezekkel a metódusokkal.)

Például ez a komponens a dokumentum címét változtatja meg azután, hogy a React frissítette a DOM-ot:

import React, { useState, useEffect } from 'react';
function Example() {
  const [count, setCount] = useState(0);

  // Hasonló a componentDidMount és componentDidUpdate-hez:  useEffect(() => {    // A dokumentum címének frissítése a böngésző API segítségével    document.title = `${count} alkalommal kattintottál`;  });
  return (
    <div>
      <p>{count} alkalommal kattintottál</p>
      <button onClick={() => setCount(count + 1)}>
        Kattints rám
      </button>
    </div>
  );
}

Amikor meghívod a useEffect-et, azt közlöd a Reacttel, hogy az futtassa a “hatás” függvényed azután, hogy a változásokat eszközölte a DOM-on. A hatások a komponensen belül vannak deklarálva, hogy hozzáférjenek a propokhoz és az állapothoz. Alapértelmezés szerint a React minden renderelés után lefuttatja ezeket a hatásokat — beleértve az első renderelést is. (A Hatás Horog használata fejezetben beszélni fogunk arról, hogy ez hogyan hasonlítható össze az osztályok életciklusaival.)

A hatások opcionálisan azt is közölhetik, hogy hogyan “takarítsanak fel” maguk után egy függvény visszaadásával. Például ez a komponens egy hatást használ egy barát online státuszára való feliratkozásához, és arról való leiratkozással takarít fel maga után:

import React, { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  useEffect(() => {    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);    return () => {      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);    };  });
  if (isOnline === null) {
    return 'Betöltés...';
  }
  return isOnline ? 'Online' : 'Offline';
}

Ebben a példában a React akkor iratkozik le a ChatAPI-ről, amikor a komponens leválik, valamint a hatás újrahívása előtt is, későbbi renderelések következtében. (Ha szeretnéd, létezik módja annak, hogy közöld a Reacttel az újrafeliratkozások átugrását, amennyiben a props.friend.id amit a ChatAPI-nek adtunk át nem változott.)

Ahogyan a useState esetében is, úgy több hatást is használhatsz egy komponensen belül:

function FriendStatusWithCounter(props) {
  const [count, setCount] = useState(0);
  useEffect(() => {    document.title = `${count} alkalommal kattintottál`;
  });

  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }
  // ...

A Horgok lehetővé teszik mellékhatások összerendezését egy komponensben a darabok összefüggését alapul véve (mint például feliratkozások hozzáadása, eltávolítása) ahelyett, hogy ezek feldarabolására kényszerülnél az életciklus metódusok miatt.

Részletes magyarázat

A Hatás Horogról az annak dedikált oldalon többet tanulhatsz: Hatás Horog használata.

✌️ A horgok szabályai

A horgok JavaScript függvények, de további két szabályt szabnak meg:

  • 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.
  • Horgokat csakis React függvénykomponensekből hívj meg. Ne hívj meg horgokat általános JavaScript függvényekből. (Csakis egy másik helye létezik a horgok szabályos meghívásának — a saját, egyedi horgaidban. Ezekről nemsokára tanulni fogunk.)

Szolgáltatunk egy linter plugint, ami ezen szabályok automatikus betartására kényszerít. Megértjük, ha ezek a szabályok elsőre korlátozónak és összezavarónak tűnnek, de alapvetőek a horgok helyes működéséhez.

Részletes magyarázat

Ezekről a szabályokról az ezeknek dedikált oldalon többet tanulhatsz: Horgok szabályai.

💡 Készítsd el a saját horgod

Néha szeretnénk állapotteljes logikát megosztani komponensek között. Hagyományosan ennek a problémának két népszerű megoldása létezett: felsőbb rendű komponensek és render propok. Az egyedi horgok ezt a problémát oldják meg, extra komponensek a komponensfádhoz való hozzáadása nélkül.

Korábban ezen az oldalon bemutattuk a FriendStatus komponenst ami meghívja a useState és useEffect horgokat egy barát online státuszára való feliratkozáshoz. Tegyük fel, hogy egy másik komponensben újra fel szeretnénk használni a feliratkozó logikát.

Először is kivonjuk a logikát egy egyedi horogba, amit useFriendStatus-nak hívunk:

import React, { useState, useEffect } from 'react';

function useFriendStatus(friendID) {  const [isOnline, setIsOnline] = useState(null);

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}

Ez egy friendID-t fogad argumentumként, és a barátunk online állapotát adja vissza.

Így már mindkét komponensben használhatjuk:

function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);
  if (isOnline === null) {
    return 'Betöltés...';
  }
  return isOnline ? 'Online' : 'Offline';
}
function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);
  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}

Ezen komponensek állapota egymástól teljesen független. A horgok az állapotteljes logika újrafelhasználásának egy módja, nem maguknak az állapotoknak. Valójában minden egyes horog meghívás állapota teljesen elzárt — szóval akár ugyanazt az egyedi horgot kétszer is használhatod egy komponensen belül.

Az egyedi horgok sokkal inkább egy közös egyezmény eredményei, mint egy egyedi funkció. Ha egy függvény neve a ”use” szóval kezdődik, és más horgokat hív meg, akkor azt mondjuk, hogy az egy egyedi horog. A useSomething elnevezési gyakorlat a módja, ami lehetővé teszi a linter pluginunknak horgokat használó kódban hibákat találni.

Írhatsz egyedi horgokat, ami a felhasználási esetek egy széles skáláját fedi le, mint például űrlapok kezelése, animációk, deklaratív feliratkozások, időzítők, és valószínűleg sok más eset, amiket nem vettünk figyelembe. Izgatottan figyeljük, hogy a React közösség milyen egyedi horgokkal rukkol elő.

Részletes magyarázat

Az egyedik horgokról az ennek dedikált oldalon többet tanulhatsz: Saját horgok készítése.

🔌 Egyéb horgok

Van néhány kevésbé használt beépített horog is, amit hasznosnak találhatsz. Például a useContext lehetővé teszi a React kontextusokra való feliratkozást, egymásba ágyazások nélkül:

function Example() {
  const locale = useContext(LocaleContext);  const theme = useContext(ThemeContext);  // ...
}

És a useReducer, ami komplex komponensek állapotának kezelését teszi lehetővé reducer-ek segítségével:

function Todos() {
  const [todos, dispatch] = useReducer(todosReducer);  // ...

Részletes magyarázat

Minden beépített horogról az ennek dedikált oldalon többet tanulhatsz: Horgok API referencia.

Következő lépések

Hűha, ez gyors volt! Ha néhány dolog nem teljesen volt világos, vagy részletesebben szeretnél valamiről tanulni, elolvashatod a következő oldalakat, kezdve az Állapot Horog dokumentációjával.

Megnézheted a Horgok API referencia oldalát, és a Horgok GY.I.K. oldalát is.

Végezetül ne hagyd ki a bemutató oldalt, ami a horgok hozzáadásának a miértjét magyarázza el, és hogy hogyan fogjuk őket osztályok mellett használni — az alkalmazásaink átírása nélkül.

Is this page useful?Az oldal szerkesztése