Lekce 8. - Metody životního cyklu React

06.04.2021 Programování #react #programování

V předchozí části jste se dozvěděli, co je lokální úložiště a jak s ním můžete začít. V této části se naučíte, jak používat lokální úložiště API k ukládání a zachování dat v aplikaci to-dos.


K tomu budete muset pochopit logiku životního cyklu. Všechny z níže uvedených metod životního cyklu se budou také probírat později v React Hooks.

Prozatím se zaměříme na základy.

Metody životního cyklu

Každá komponenta v Reactu, kterou vytvoříte, vždy prochází řadou fází od narození po zánik. Můžete si představit, že tyto komponenty procházejí cyklem zrození, růstu a nakonec zániku.

V každé fázi existují metody životního cyklu, které reagují na volání, aby provedly některé určité funkce. React nám umožňuje tyto metody přepsat. Ale než se k tomu dostaneme, pojďme stručně probrat jednotlivé fáze.

V Reactu jsou tři hlavní fáze.

  1. Připojení: Jak název napovídá, jedná se o fázi, kdy komponenta Reactu připojí (vytvoří a vloží) DOM. V této fázi se rodí komponenta.

  2. Aktualizace: Jakmile je komponenta připojena, mohla by se aktualizovat. Uvědomte si, že komponenta se aktualizuje v případě, že je / jsou state nebo prop změněny, tedy se jedná po spoušť opětovného vykreslování. To vše se děje v této fázi.

  3. Odpojení: Tato fáze končí životní cyklus komponenty, protože v ní je komponenta odebrána z DOM.

V každé z těchto fází poskytuje React metody životního cyklu, které můžeme použít k monitorování a manipulaci s tím, co se děje v komponentě.

Již jsme používali jednu z těchto metod životního cyklu - metodu render(). Tato metoda je jedinou povinnou metodou životního cyklu v rámci komponenty třídy React. Je zodpovědný za vykreslení prvků React ve virtuálním DOM a volá se během fáze připojení a aktualizace.

React má několik volitelných metod životního cyklu, z nichž některé jsou zastaralé nebo existují pro výjimečný případ použití.

Mezi běžné metody, kromě render() však patří:

  • componentDidMount () - Tato metoda životního cyklu se volá okamžitě po vykreslení komponenty.

  • componentDidUpdate () - Volá se okamžitě po aktualizaci.

  • componentWillUnmount () - Volá se těsně před odpojením nebo zničením komponenty.

Podívejme se podrobněji na každou z metod.

Metoda componentDidMount()

Jak již bylo zmíněno dříve, volá se ihned po vykreslení komponenty. Stejně jako metoda render() patří do iniciační fáze. Jen render() je vyvoláno před Reactem, aktualizuje skutečný DOM.

Pro začátek budete pracovat s componentDidMount(). Důvodem je, že budete často provádět nějaké efekty (nebo vedlejší efekty). Například vytvoření síťového požadavku, nastavení časovače, nastavení odposlechů událostí atd. Jsou to příklady vedlejších účinků, které můžete v této metodě provést.

Až se dostaneme k funkčním hákům, podrobně je probereme. Prozatím vězte, že o funkci se říká, že má vedlejší účinky, pokud změní něco mimo její tělo. Díky tomu se nazývá jako nečistá funkce.

Jak možná víte, třídy jsou také typovou funkcí.

Tyto efekty nejsou v metodě render() povoleny. Nejen proto, že vykreslení by mělo být udržováno čisté, ale také je vyvoláno příliš brzy. A chtěli byste provést některý z těchto vedlejších účinků poté, co React aktualizuje DOM.

Metoda componentDidMount() je tedy dobrým místem k provádění těchto typů operací. Zajišťuje, že vaše data budou provedena okamžitě, když komponenta připojí DOM.

Uvidíme později, jak můžeme tuto metodu využít a číst naše todos položky z lokálního úložiště. Prozatím se podíváme na běžný případ použití.

Načítání dat ze vzdáleného koncového bodu

V naší aplikaci todos můžeme dělat všechny druhy požadavků HTTP (jako GET, POST nebo DELETE dat) do a ze vzdáleného koncového bodu. Takže místo toho, abychom ručně přidávali výchozí položky úkolů, můžeme požadovat data ze serveru a vypsat je na frontendu.

Tato data můžeme získat z jakéhokoli backendu, ale zde využijeme bezplatné online REST API s názvem JSONPlaceholder. Umožňuje nám napodobit skutečný živý server a mít backend pro práci. Odtud můžeme do naší aplikace úkolů získat seznam falešných položek todos.

K načtení dat použijeme k provedení tohoto požadavku metodu fetch() z nativního Fetch API a zpracujeme odpovědi. Můžeme také použít knihovnu jako je Axios.

Pokud otevřete web JSONPlaceholder a kliknete na odkaz todos v sekci Zdroje, zobrazí se seznam 200 todos, se kterými budeme pracovat. Poznamenejte si adresu URL, vytvoříme na ni požadavek HTTP.

Otevřete komponentu TodoContainer a odstraňte všechna data todos. Objekt state nyní vypadá takto:

state = {
  todos: [],
}

Uložte soubor a uvidíte, že vaše aplikace zobrazuje prázdné výchozí položky. Dále v souboru přidejte následující kód kdekoli nad render().

componentDidMount() {
  fetch("https://jsonplaceholder.typicode.com/todos")
    .then(response => response.json())
    .then(data => console.log(data));
}

Uložte soubor a podívejte se do konzoly. Zobrazí se seznam objektů obsahujících data úkolů.

Toto je nejjednodušší použití metody fetch().

Kód je jednoduchý a přímočarý. Již víme, že když se komponenta vykreslí do DOMu, provede se cokoli, co je umístěno v metodě životního cyklu componentDidMount(). V našem případě dostáváme seznam dat úkolů zobrazených v konzole.

V metodě životního cyklu jsme začali vytvořením požadavku na zadanou adresu URL. To pak vrátí příslib obsahující odpověď HTTP. Data zde nejsou pro nás užitečná. Takže jsme vyřešili odpověď do formátu JSON, kde pak dostáváme data ve formátu, se kterým můžeme pracovat.

Pro stručnost můžeme omezit počet úkolů na 10 namísto 200 načítaných položek.

Aktualizujte tedy adresu URL požadavku připojením řetězce dotazu.

componentDidMount() {
  fetch("https://jsonplaceholder.typicode.com/todos?_limit=10")
    ...
}

Chcete-li zobrazit svá data, podívejte se do konzoly.

Nyní můžeme s těmito daty aktualizovat stav. Podle očekávání použijeme metodu setState().

Aktualizujte kód, abyste měli:

componentDidMount() {
  fetch("https://jsonplaceholder.typicode.com/todos?_limit=10")
    .then(response => response.json())
    .then(data => this.setState({ todos: data }));
}

Uložte soubor a znovu načtěte aplikaci. Měli byste vidět své úkoly.

Stejným způsobem můžete použít metodu fetch() k vytvoření příspěvku a odstranění požadavku na JSONPlaceholder nebo na jakýkoli backend.

Prozatím probereme další důležitou metodu životního cyklu. K componentDidMount se vrátíme, když začneme trvale uchovávat data todos v úložišti prohlížeče.

Metoda componentDidUpdate()

Toto je další důležitá metoda životního cyklu, která umožňuje definovat vedlejší aktivity. Jak jsem již zmínil dříve, volá se ihned po aktualizaci - tj. po změně stavu nebo vlastností.

Je tedy ideální, když potřebujete provést operaci po aktualizaci DOM. Manipulace s DOM, načítání dat, ke kterému dochází pouze při splnění konkrétní podmínky atd., jsou operace, které mohou jít do tohoto životního cyklu.

Chcete-li jej použít, budete mít něco takového:

componentDidUpdate(prevProps, prevState) {
  // update logic here
}

Argumenty metody nám umožňují porovnat prevProps nebo prevState s jejich aktuálním pohledem uvnitř componentDidUpdate. Tím je zajištěno, že můžeme kontrolovat, jak často životní cyklus běží po aktualizaci komponenty. Bez těchto parametrů může běžet nekonečně, pokud má výzvu k aktualizaci stavu. Je to proto, že setState způsobí nové vykreslení.

Můžeme to ovládat tak, že napíšeme další srovnání takto:

componentDidUpdate(prevProps, prevState) {
  if(prevState.todos !== this.state.todos) {
    // logic here
  }
}

prevProps prevState jsou prostě stavy a vlastnosti před aktualizací. Používáme je k přeskočení použití efektu, pokud se mezi opětovným vykreslením určité hodnoty nezměnily.

Bez ohledu na to, zda voláte za účelem aktualizace stavu, je vždy vaší povinností v životním cyklu mít kontrolu.

Stejně jako stav můžete také porovnat prevProps s jeho aktuálním pohledem, pokud má komponenta přístup k prop.

Uchování dat úkolů v lokálním úložišti

Nyní, když víte, co jsou componentDidMount componentDidUpdate, budeme je používat v procesu ukládání a načítání dat z úložiště prohlížeče.

Logika zde je jednoduchá. Kdykoli se naše aplikace připojí na obrazovku a uživatel s aplikací interaguje zadáním dat úkolů, uložíme položky úkolů do lokálního úložiště. Zní to, jako by programová logika měla být v componentDidUpdate. Ano jet to tak.

Při připojení komponent (tj. Při opětovném načtení stránky nebo při následné návštěvě) však zkontrolujeme, zda jsou v lokálním úložišti přítomny položky úkolů. Zní to, jako by logika měla být v componentDidMount.

K dosažení tohoto cíle použijeme metody lokálního úložiště.

Začněme tedy ukládáním úkolů (pokud existují) do lokálního úložiště.

Pamatujte, že již dříve jsme metodu componentDidMount přidali do komponenty TodoContainer. Nyní to smažeme. Pole stavu todos můžete nechat prázdné tak, jak je.

Nyní přidáme následující kód kamkoli nad metodu render().

componentDidUpdate(prevProps, prevState) {
  if(prevState.todos !== this.state.todos) {
    const temp = JSON.stringify(this.state.todos)
    localStorage.setItem("todos", temp)
  }
}

Jediné, co v životním cyklu děláme, je získávání aktuálních úkolů a jejich ukládání do lokálního úložiště. Nezapomeňte, že React spustí kód, jakmile zjistí aktualizaci.

Uložte soubor a otevřete úložiště prohlížeče. Jakmile přidáte položku todos, uvidíte ji v lokálním úložišti. I když po opětovném načtení stránky ztratíte položku v zobrazení, máte ji uloženou v úložišti. To je logické, protože neustále načítáme data ze serveru.

Stále v souboru ToDoContainer.js přidejte následující kód kamkoli nad metodu render().

componentDidMount() {
  const temp = localStorage.getItem("todos")
  const loadedTodos = JSON.parse(temp)
  if (loadedTodos) {
    this.setState({
      todos: loadedTodos
    })
  }
}

Uložte soubor a znovu načtěte stránku.

Jakmile se komponenta připojí, měli byste získat uložená data z lokálního uložiště. Nyní budou všechna data, která přidáte nebo upravíte, přetrvávat v lokálním úložišti a budou k dispozici kdykoli.

V kódu jednoduše získáme data z úložiště a pomocí metody setState() aktualizujeme stav .

Použití setState přímo v životním cyklu componentDidMount

Volání setState() v této metodě by vyvolalo další vykreslení. To znamená, že metoda render() bude volána dvakrát. Je to v pořádku, protože k tomu dojde dříve, než prohlížeč aktualizuje zobrazení. Měli bychom to vždy používat opatrně nebo se mu jednoduše vyhnout, pokud můžete zabránit jakémukoli problému s výkonem.

Protože v našem případě chceme zobrazit uložené položky po vykreslení komponenty, můžeme položky jednoduše přiřadit přímo jako počáteční stav.

Na to se podíváme, až se dostaneme k funkčním hákům.

Metoda componentWillUnmount()

Některé komponenty v Reactu vyžadují uvolnění prostředků, jakmile budou odstraněny ze zobrazení. Dříve jsme zmínili, jak nám componentDidMount umožňuje provádět vedlejší účinky, jako je požadavek na síťový požadavek, nastavení časovače nebo vlastností. Jakmile je komponenta (provádějící tyto efekty) odstraněna z DOM, chtěli bychom provést vyčištění, jako je zrušení požadavku na síť, zneplatnění časovačů, odebrání posluchačů událostí nebo vyčištění jakéhokoli vlastnosti. To je nezbytné, aby se zabránilo úniku paměti.

Metoda životního cyklu, kterou React volá v této fázi (tj. Když má být součást zničena nebo odstraněna z DOM), je metoda componentWillUnmount().

Abychom si ukázali, jak to funguje, budeme protokolovat zprávu do konzoly, kdykoli bude některá z položek todos odstraněna z DOM.

Takže otevřete soubor TodoItem.js a přidejte tento kód kamkoliv nad metodu render():

componentWillUnmount() {
  console.log("Cleaning up...")
}

Uložte soubor.

Nyní odzkoušejte tím, že kliknete na tlačítko pro odstranění.

Otevřete konzolu prohlížeče a zkuste odstranit všechny položky úkolů. Měla by se zobrazit zpráva protokolu.

Toto je jen ukázka. Ve vašem případě možná budete muset udělat nějaké vyčištění. Tato metoda životního cyklu je pro to ideálním místem.

Zatím jste se na této stránce dozvěděli, jaké jsou metody životního cyklu React a jak je můžete ve své aplikaci použít. Také jste se naučili, jak je využít v procesu přetrvávajících dat v lokálném úložišti.