Podstawy React’a: stan i useState
Zaczynając swoją przygodę z React’em, który obecnie jest jednym z najczęściej używanych framework’ów front-end’owych, natkniesz się pojęcie stanu i towarzyszący mu hook useState, który dla osób początkujących może być niezrozumiały. W tym artykule postaram się wytłumaczyć o co w tym wszystkim chodzi, używając prostego języka.
Czym jest stan?
To jedno z pytań które możesz sobie zadać na początku nauki, ale także pytanie które możesz usłyszeć podczas swojej rozmowy kwalifikacyjnej. Dlatego warto przeczytać kilka definicji i… napisać od nowa swoją, ponieważ zrozumienie koncepcji stanu jest kluczowe podczas Twojej nauki.
Według mojej definicji stan to wszystkie dane (teksty, liczby, obiekty, tablice) które definiują funkcjonalność naszej aplikacji (bądź jej części) i to, jak ona działa.
Najprostszy przykład stanu? Mobile Menu, który możecie znaleźć na większości stron internetowych. Oto pseudo-kod który pomoże Ci zrozumieć o czym piszę. Naszym stanem jest zmienna “openMenu”
openMenu = falseFunkcja toggleMobileMenu { jeżeli openMenu ma wartość false { Zmień openMenu na true } jeżeli openMenu ma wartość true { Zmien openMenu na false }}Jeżeli openMenu === true, otwórz MobileMenu
I za pomocą takiego kodu możesz otwierać i zamykać menu. Funkcja toggleMobileMenu powinna być podpięta pod button, który w żargonie nazywa się “hamburger menu”.
Inne, bardziej skomplikowane przykłady stanu? Np. zalogowany użytkownik, albo pobrane z API dane, ale nie zajmuj sobie tym głowy. Skupiamy się na podstawach.
Czym są hooki?
Pierwszym zagadnieniem które warto poruszyć jest “hook”. Oficjalna dokumentacja Reacta opisuje go jako:
Hooki są to funkcje, które pozwalają „zahaczyć się” w mechanizmy stanu i cyklu życia Reacta, z wewnątrz komponentów funkcyjnych. Hooki nie działają w klasach - zamiast tego pozwalają korzystać z Reacta bez klas.
Link: Hooki w pigułce
Powiedzmy sobie szczerze - gdy zaczynasz przygodę z React’em i czytasz za pierwszym razem dokumentacje - nic z tego nie rozumiesz. To normalne. Stan, cykl życia, klasy. Dużo nowych pojęć, które ciężko zrozumieć na początku, dlatego na razie skupmy się na rzeczach które pozwolą nam zrozumieć podstawy. Sprowadźmy to do mojej uproszczonej definicji.
Hooki to funkcje, które są znakiem rozpoznawczym React’a. Pozwalają nam manipulować naszą stroną / aplikacją / stanem niejako za naszymi plecami, bez dogłębnej wiedzy, jak to się dzieje. Mamy hooki do zarządzania stanem, aktualizacji komponentów (czyli wydzielonych kawałków kodu jak np. navbar czy modal), optymalizacji kodu. Jest ich wiele, ale na sam początek wystarczą Ci dwa: useState (o którym zaraz) i useEffect.
Jak używać useState?
Hook useState pomaga nam kontrolować stan naszej aplikacji. Aby go użyć musimy zacząć od zaimportowania go. Najprościej będzie zrobić to na samej górze kodu. Hook importujesz w każdym pliku .js w którym chcesz go używać. Masz stan w App.js? Wklej go do App.js. Cały kod będzie dostępny na samym dole.
import { useState } from "react";
Kolejnym krokiem będzie zdefiniowanie hooka w kodzie. Aby to zrobić wklej go do funkcji (nad returnem)
function App() { const [openMenu, setOpenMenu] = useState(false); return ();}
O co tu chodzi? Pozwól, że wyjaśnię.
openMenu to nasza zmienna (taka sama jak podczas deklarowania w JavaScript przez const, let, var)
setOpenMenu to funkcja, która odpowiedzialna jest za całą magię. Jej zadaniem jest sprawować kontrolę nad tym, jak nasza zmienna openMenu się zmienia, dlatego za jej pomocą będziemy zmieniać nasz stan czyli openMenu. Do tego mamy dwa nawiasy klamrowe [] które są niczym innym jak przypisaniem destrukturyzującym i niejako ukrywają przed nami co dzieje się pod maską tego hook’a.
Jeżeli chodzi o nazewnictwo, zmienną możemy nazwać jak chcemy, funkcję nazywamy dokładając przedrostek set czyli name, setName albo data, setData.
useState(false) - czyli nasz Reactowy hook z wartością początkową naszego stanu.
Reasumując - mamy zmienną openMenu, która będzie zarządzać naszym menu, setOpenMenu zadba o to, żeby wszystkie zmiany stanu były śledzone, a wartością początkową jest boolean false, bo chcemy zacząć od zamkniętego menu.
Okej, a jak zmieniać stan? Najlepiej w tym wypadku będzie napisać funkcję toggleMobileMenu którą podepniemy pod button’a.
const toggleMobileMenu = () => { setOpenMenu(!openMenu);};
Co dzieje się wewnątrz funkcji? Używamy setOpenMenu jako opakowania. Mówimy przez to naszemu stanowi “Hej, to co jest między nawiasami to Twoja nowa wartość, lepiej miej na nią oko!” . OpenMenu to nic innego jak JavaScriptowy skrót, który w tym momencie mówi: “openMenu ma wartość true? To daj false! openMenu ma false? To teraz będzie true.” To klasyczny toggle i gwarantuję Ci - podczas swojej kariery będziesz bardzo dużo togglował/a!
To chyba najwyższa pora, aby nasz pseudo kod rozpisać w Reakcie.
App.js
import { useState } from "react"; // Importujemy useStateimport "./App.css";function App() { const [openMenu, setOpenMenu] = useState(false); // Inicjujemy useState ze zmienną openMenu jako false const toggleMobileMenu = () => { setOpenMenu(!openMenu); }; // Funkcja które zmienia stan na odwrotny, z false na true, z true na false return (<div className="App"><button onClick={toggleMobileMenu} class="hamburger-menu"><span></span><span></span><span></span></button> // Nasz “hamburger menu” {openMenu && (<div className="menu"><ul><li>Home</li><li>About</li><li>Contact</li></ul></div> // openMenu && () czyli jeżeli openMenu === true, pokaż menu, jak false - nie )}</div> );}export default App;
App.css
.App { display: flex; flex-direction: row-reverse; justify-content: flex-start; align-items: flex-start; margin: 20px;}button { background-color: transparent; border: 0; cursor: pointer;}.hamburger-menu span { display: block; width: 30px; height: 5px; margin-bottom: 5px; background: #cdcdcd; border-radius: 3px;}.hamburger-menu span:first-child { transform-origin: 0% 0%;}.hamburger-menu span:nth-last-child(2) { transform-origin: 0% 100%;}.menu { display: flex; flex-direction: column; justify-content: center; align-items: center; width: 500px; height: 300px; background-color: rgb(34, 37, 36); color: aliceblue;}.menu ul li { text-align: center; list-style: none; font-size: 50px; cursor: pointer;}
Warto również zaznaczyć że w naszym projekcie możemy mieć kilka stanów. Np. w navbarze stan odpowiadający za otwieranie i zamykanie menu, w App.js stan przechowujący pobrane informację z API czy też przełączniku między trybem jasnym i ciemnym szablonu naszej strony (popularny light/dark theme toggle).
Artykuł ten nie wyczerpał tematu useState, ale powinien rzucić trochę światła osobom które dopiero zaczynają z Reactem. Bez wątpienia są to podstawy, bez zrozumienia których nie ma sensu kontynuować nauki.
Kod na codepen.