- Wprowadzenie do kursu React.js od podstaw
- Poznaj React.js
- Pierwszy komponent w React.js
- Props czyli atrybuty w React.js
- Podział na komponenty w React.js
- Klasy jako komponenty React.js
- Interakcja z komponentami React.js
- Stan komponentów React.js
- State w React.js 2
- Metody cyklu życia komponentu w React.js
- React.js w przykładach: filtrowanie statycznej listy
- Tworzenie aplikacji React.js dzięki create-react-app
- React.js na GitHub Pages dzięki create-react-app
- Testowanie aplikacji React.js — podstawy Enzyme
- Testowanie React.js w Enzyme — props, state i interakcje
- Poprawne bindowanie funkcji w React.js
- Odpowiadam na pytania: Babel, ECMAScript, destrukturyzacja, onClick, className
- Komunikacja pomiędzy komponentami w React.js
- Komunikacja z API w React.js
- Formularze w React.js — kontrolowane komponenty
- Formularze w React.js — niekontrolowane komponenty
- Odpowiadam na pytania: props, nawiasy klamrowe, funkcje vs klasy, import react
- Flux i Redux
- React + Redux — kurs: wprowadzenie i podstawy
- TDD w React.js z pomocą react-testing-library
Przyszedł czas na poznanie tajemniczego state
w React.js. Udało nam się tworzyć komponenty, które pięknie wyświetlały przekazane propsy, ale trzeba przyznać szczerze: Bez wewnątrznego stanu nie da się zbudować funkcjonalnej aplikacji. Dzisiaj nauczysz się taki stan dodawać i wykorzystywać 🙂
Zacznijmy może od typowego przykładu powielonego w wielu kursach: Licznika. Stwórz komponent, który ma dwa przyciski (plus i minus) oraz output
na wyświetlanie wyniku. Początkowo wartość wynosi 0, kliknięcie w przycisk odpowiednio zwiększa lub zmniejsza liczbę. Umiesz już obsłużyć kliknięcia, potrafisz też wyświetlać dane. Jak jednak je modyfikować?
Propsy są niemutowalne
Propsów nie da się zmienić z wnętrza komponentu. A jeśli spróbujesz to pewnie Ci się uda, ale będziesz mieć ogromne problemy — niespójne dane na ekranie, a może nawet jakieś błędy. Generalnie: Straszne rzeczy. Co do zasady: Propsów nie zmieniamy z wnętrza komponentu, do którego zostały one przekazane. I kropka.
Wchodzi state
A więc tutaj pojawia się słynny state. Do czego służy? Do przechowywania stanu komponentu. Ponadto, state można mutować dzięki funkcji setState
. A więc jest to dokładnie ten brakujący element układanki, którego poszukujemy! Tak, tak, to właśnie w state
będziesz przechowywać licznik, który chcesz zaimplementować.
Jeszcze jedna mała uwaga: Do state
nie dobierzesz się w funkcyjnych komponentach. Stąd też ich nazwa: Stateless Functional Components. Potrzebna będzie klasa. Skoro to jest już jasne, weźmy się za pisanie kodu:
class App extends React.Component {
render() {
return (
<div>
<button>+</button>
<output>{this.state.counter}</output>
<button>-</button>
</div>
);
}
}
Tak mniej-więcej będzie wyglądała nasza funkcja render
. Jednak jeśli teraz odpalisz ten kod to dostaniesz w konsoli wyjątek, coś podobnego do Cannot read property 'counter' of null
. Chwila drapania się po głowie i… no jasne, przecież nigdzie nie podaliśmy czym w ogóle jest state
! Do tego potrzebny nam będzie konstruktor klasy. Dopisz na początku swojego komponentu:
constructor() {
super();
this.state = {counter: 0};
}
Przypomnę tylko, że jeśli klasa po czymś dziedziczy (tak jak tutaj po React.Component
) to wewnątrz konstruktora musisz wywołać super()
. Potem ustawiasz state
na taki, jaki ma on być domyślnie — zanim zostaną wykonane jakiekolwiek akcje przez użytkownika. Teraz aplikacja renderuje się poprawnie, aczkolwiek nic spektakularnego się jeszcze nie dzieje!
this
w React
Dopisujemy dwa onClick
do przycisków i dwie metody w klasie: Jedna do zwiększania, a druga do zmniejszania wartości w liczniku. Posłuży do tego funkcja setState
, w której odpowiednio ustawiamy licznik na (obecna wartość + 1
) lub (obecna wartość - 1
):
<button onClick={this.increment}>+</button>
increment() {
this.setState({
counter: this.state.counter + 1
})
}
Jednak po kliknięciu w przycisk dostajemy tylko błąd: Cannot read property 'setState' of undefined
. Cooo?
Wspominałem, że przy klasach pojawi nam się błąd związany z this
. Każdy kto zna JS widzi już w czym problem: this
w momencie wywołania funkcji increment
nie jest związane z instancją komponentu. Jak rozwiązać ten problem?
Jest kilka sposobów, które omówię później. Na razie weźmiemy najprostszy: bind
. Zmień kod w JSX:
<button onClick={this.increment.bind(this)}>+</button>
Woah, działa!
bind
jest najprostszym rozwiązaniem, ale wcale nie najlepszym. Sam może stwarzać problemy, np. z wydajnością albo z tym, że referencja do funkcji się za każdym razem zmienia… Powrócę do tego tematu wkrótce.
Demo
Nauczyłaś/eś się używać state
w React.js. Na razie w prosty sposób, ale ten temat jeszcze rozwinę w kolejnym wpisie. Tymczasem demo:
See the Pen Stan komponentów React.js by Michał Miszczyszyn (@mmiszy) on CodePen.
Ćwiczenie
Ćwiczenie: Dodaj dwa nowe liczniki. Pierwszy, który będzie zliczał wszystkie kliknięcia w przyciski (tzn. kliknięcie w +
i -
daje 0 na obecnym liczniku oraz 2 na nowym liczniku), oraz drugi, który będzie zliczał podwójne kliknięcia (tzw. double click) na elemencie z wynikiem. Jak wygląda teraz Twój state
? Czy napotkałaś/eś jakieś problemy, albo coś Cię zaskoczyło? Napisz o tym w komentarzu 🙂
- Wprowadzenie do kursu React.js od podstaw
- Poznaj React.js
- Pierwszy komponent w React.js
- Props czyli atrybuty w React.js
- Podział na komponenty w React.js
- Klasy jako komponenty React.js
- Interakcja z komponentami React.js
- Stan komponentów React.js
- State w React.js 2
- Metody cyklu życia komponentu w React.js
- React.js w przykładach: filtrowanie statycznej listy
- Tworzenie aplikacji React.js dzięki create-react-app
- React.js na GitHub Pages dzięki create-react-app
- Testowanie aplikacji React.js — podstawy Enzyme
- Testowanie React.js w Enzyme — props, state i interakcje
- Poprawne bindowanie funkcji w React.js
- Odpowiadam na pytania: Babel, ECMAScript, destrukturyzacja, onClick, className
- Komunikacja pomiędzy komponentami w React.js
- Komunikacja z API w React.js
- Formularze w React.js — kontrolowane komponenty
- Formularze w React.js — niekontrolowane komponenty
- Odpowiadam na pytania: props, nawiasy klamrowe, funkcje vs klasy, import react
- Flux i Redux
- React + Redux — kurs: wprowadzenie i podstawy
- TDD w React.js z pomocą react-testing-library