Z wpisem, w którym przedstawię podstawy ReactJS nosiłem się już od bardzo dawna… Dotychczas opublikowałem kilka postów niejako przygotowujących pod ten temat. Dlatego też ostatnio pisałem na przykład o podstawach konfiguracji Webpacka.

Przez ostatni rok pracowałem głównie właśnie w środowisku ReactJS dlatego mam w zanadrzu mnóstwo artykułów na ten temat. Uznałem jednak, że nie mogę nic na ten temat napisać zanim na blogu nie pojawi się konkretny wstęp do tego tematu. Z tego też powodu dziś przedstawiam kompletny poradnik jak zacząć pracę z Reactem. W dalszej części wpisu przedstawię też oczywiście absolutne podstawy ReactJS!

Przygotowanie projektu

Wydaje mi się, że najlepiej będzie pokazać Ci podstawy ReactJS na przykładzie jakiejś prostej aplikacji. Dlatego też, zanim przejdę do konkretów, postawimy sobie nowy projekt ReactJS za pomocą mojego ulubionego narzędzia Yeoman.

Utworzenie projektu z generatora

Jeżeli nie słyszałeś jeszcze o tym narzędziu, to zachęcam do uprzedniego zapoznania się z moim wpisem na jego temat. Jeżeli nie masz jeszcze zainstalowanego Yeomana, to czym prędzej to zrób za pomocą wywołania poniższej komendy w konsoli:

npm install -g yo

Następna sprawa to zainstalowanie odpowiedniego generatora, który utworzy nam wszystko co niezbędne do pracy nad projektem w ReactJS. Na potrzeby tego wpisu wybrałem już dla Ciebie odpowiedni generator. Aby go zainstalować, należy użyć poniższej komendy:

npm install -g generator-react-webpack

Ostatnia rzecz, to uruchomienie generatora w katalogu projektu. Oczywiście najpierw utwórz odpowiedni katalog na ten projekt. Następnie przejdź do niego w konsoli i uruchom poniższą komendę.

yo react-webpack

Powyższa komenda potworzy wszystkie niezbędne katalogi i pliki, a następnie uruchomi komendę npm install. Gdy i to się skończy, nasz projekt jest gotowy do dalszej pracy.

P.S. Na końcu tego artykułu znajdziesz link do repozytorium GitHub, w którym znajduje się cały kod przykładowej aplikacji stworzonej w ramach tego pisania tego posta. Zawiera on wszystko to co zostało tutaj wygenerowane oraz implementację kolejnych kroków tego przykładu.

Przegląd dostępnych komend

Zanim przejdę do właściwej części tego wpisu i przedstawię podstawy ReactJS myślę, że warto najpierw przedstawić Ci projekt, który właśnie utworzyliśmy.

Po pierwsze projekt oparty jest na Webpacku wspartym skryptami NodeJS. Dzięki temu dostajemy na starcie kilka akcji, które służą do uruchamiania aplikacji w trybie deweloperskim, budowanie aplikacji na produkcję czy uruchamianie testów. Akcje te odpala się oczywiście z poziomu konsoli, będąc w głównym katalogu projektu. Poniżej lista dostępnych akcji:

# uruchomienie w trybie dev
npm start # lub
npm run serve

# uruchomienie wykorzystując pliki z katalogu dist
npm run serve:dist

# generowanie plików do katalogu dist + kopiowanie zasobów statycznych
npm run dist

# urumienie testów
npm test

# uruchomienie testów wraz z re-testem przy zmianie pliku
npm run test:watch

# uruchomienie lintera (dzieje się też automatycznie po testach)
npm run lint

# czyszczenie katalogu dist
npm run clean

# kopiowanie statycznych zasobów
npm run copy

Jeśli jesteś ciekawy jak są zdefiniowane te zadania, zajrzyj koniecznie do pliku package.json znajdującego się w głównym katalogu projektu. Jest to zwykły plik JSON zawierający konfigurację projektu NPM. To co nas interesuje to właściwość scripts. To tutaj zdefiniowane są wszystkie powyższe zadania. Jak widzisz, wykorzystują one po prostu różne komendy NodeJS do wykonywania zadań. Gulp nie jest nam tutaj potrzebny…

Próbne uruchomienie

Dla testu możemy teraz uruchomić naszą aplikację:

npm start

To powinno uruchomić aplikację w trybie deweloperskim. To znaczy, że Webpack wykona wszystkie swoje operacje “w locie” i przekaże ich efekt do lokalnego serwera deweloperskiego dla Webpacka. Uruchomienie powyższej komendy spowodować powinno otwarcie nowej karty w Twojej przeglądarce i wczytanie strony http://localhost:8000/webpack-dev-server. Jeśli to nie nastąpi a w konsoli nie dostałeś żadnych błędów, spróbuj sam wpisać ten adres. Adres ten możesz następnie zmienić na http://localhost:8000 - wtedy zniknie ta dodatkowa ramka dodawana przez serwer.

UWAGA! W momencie gdy pisałem ten wpis, użyty przeze mnie generator miał nieaktualną jedną z zależności - react-hot-reloader. Należało go zaktualizować oraz zmienić nieco konfigurację: Usunąć odwołanie w definicji loadera Webpacka oraz dodać odpowiedni plugin do pliku .babelrc. Poprawka ta jest już naniesiona w repozytorium zawierającym dzisiejszy przykład, dostępnym w GitHubie (link do niego na końcu wpisu).

Niestety w miarę jak pojawiać się będą nowe wersje różnych pakietów używanych w projekcie, mogą pojawiać się inne tego typu problemy, które będziesz musiał rozwiązywać już we własnym zakresie…

Generalnie, tryb deweloperski jest bardzo przydatny. Posiada on funkcję “hot-reload” to znaczy, że strona powinna odświeżać się automatycznie w momencie zapisania zmian, w którymś z plików projektu.

W przyszłości, jeśli chciałbyś ten projekt wystawić gdzieś na serwerze, musiałbyś użyć komendy:

npm run dist

To spowoduje uruchomienie zadań Webpacka, które następnie trafią do katalogu dist. Oprócz tego, do katalogu tego skopiowane zostaną wszystkie pliki statyczne, takie jak obrazki itp.

Struktura projektu

Przejrzyjmy się teraz katalogom projektu. Po pierwsze katalog cfg - znajdują się tutaj pliki zawierające różne warianty konfiguracji Webpacka. Jeśli chcesz dodać, na przykład, jakiś dodatkowy loader to właśnie jest miejsce aby to zrobić. Zwróć uwagę na plik base.js - jest to wspólna konfiguracja dla wszystkich trybów. Ponadto mamy tutaj pliki specyficzne dla trybu “dev”, “dist” oraz “test”. Wykorzystaj je, jeśli potrzebujesz zmienić konfigurację tylko dla jednego z trybów. Plik defaults zawiera ustawienia domyślne, takie jak na przykład port dla serwera deweloperskiego itp.

Następny katalog nosi nazwę dist. Tutaj trafiają pliki przeznaczone na produkcję. Myślę, że nie ma sensu nic więcej w tej kwestii pisać… Dodatkowo, jeśli uruchomiłeś już polecenie npm install to masz też u siebie katalog node_modules zawierający wszystkie niezbędne zależności projektu.

Kolejnym katalogiem jest src. To w zasadzie najważniejszy katalog naszego projektu ponieważ, zawiera kod źródłowy naszej aplikacji. Za chwilę napiszę więcej o jego zawartości.

Na koniec katalog test. Myślę, że nazwa mówi sama za siebie… Generalnie jego struktura odpowiada strukturze katalogu src - każdy z katalogów ma zawierać testy kodu znajdującego się w poszczególnych katalogach. Testowanie aplikacji ReactJS nie jest tematem dzisiejszego wpisu, dlatego nie będę się tutaj na ten temat rozwodzić. Napiszę tylko, że testy w naszym projekcie realizowane są w oparciu o następujące biblioteki/frameworki: Karma oraz Mocha/Chai.

Podstawy ReactJS - konfiguracja renderowania

Ok. Skoro projekt mamy już przygotowany i próbnie odpalony to myślę, że czas przejść do mięcha… A, że staram się pokazać Ci absolutne podstawy ReactJS to myślę, że należy zacząć zupełnie od początku.

Plik index.html

Zgodnie z obietnicą, wróćmy teraz do katalogu src. Znajdziesz w nim dwa pliki: index.html oraz index.js. Pierwszy z nich to zwykły plik HTML, który jest punktem startowym naszej aplikacji. To właśnie on serwowany jest przez nasz lokalny serwer podczas pracy nad projektem. Pomińmy to co znajduje się w sekcji “head” i od razu przejdźmy do “body”:

<div id="app">APPLICATION CONTENT</div>

<script>
  __REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__
</script>
<script type="text/javascript" src="/assets/app.js"></script>

To co tutaj jest najbardziej interesujące to element div o indeksie “app”. To wewnątrz tego elementu ReactJS będzie się renderować. Pozostałe dwa skrypty odpowiadają odpowiednia za, kolejno: konfigurację wtyczki React Devtools (warto ją sobie zainstalować) tak aby działała również w IFrame; załadowanie pliku z projektem wygenerowanym przez Webpacka.

Tutaj małe wyjaśnienie co do drugiego ze skryptów. Jak wiesz Webpack generuje paczkę na podstawie plików projektu. Jeśli zajrzysz do pliku cfg/base.js to zobaczysz, że paczka ta trafia do pliku app.js w katalogu assets. Dlatego też musimy go załadować w pliku HTML.

Plik index.js

Drugim istotnym plikiem w katalogu src jest index.js. To on jest punktem startowym dla Webpacka. Spójrz na jego zawartość, a następnie go przeanalizujemy:

import 'core-js/fn/object/assign';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/Main';

// Render the main component into the dom
ReactDOM.render(<App />, document.getElementById('app'));

Jak możesz zauważyć, na początku pliku mamy serię importów. Jest to oczywiście importowanie modułów w stylu ES6. Najważniejsze są trzy ostatnie importy. Pierwszy to po prostu import ReactJS. Import ten musi występować w każdym module zawierającym implementację komponentu. Jak widzisz w punkcie startowym aplikacji również jest on wymagany.

Poza importem modułu react, potrzebujemy jeszcze modułu react-dom. Pozwoli nam on na wyrenderowanie naszej aplikacji. Na koniec mamy import komponentu ./components/Main. Jest to główny komponent naszej aplikacji - zawiera on odwołania do innych komponentów itd. Ale o tym później.

Przejdźmy teraz do ostatniej linii powyższego kodu. Jak widzisz, wywołujemy metodę render obiektu ReactDOM, który uprzednio zaimportowaliśmy z modułu react-dom. Przekazujemy do niego dwa parametry: pierwszy to główny komponent naszej aplikacji. Drugi natomiast to element drzewa DOM, wewnątrz którego ma nastąpić renderowanie. Jest to jak widać, element div o indeksie app, o którym była mowa przy okazji omawiania pliku index.html.

Główny komponent aplikacji

Wspomniałem przed momentem, że w pliku index.js zaimportowaliśmy główny komponent aplikacji (plik src/comonents/Main.js). Po utworzeniu projektu z generatora ma on już przykładową implementację. Na potrzeby tego tutoriala, proponuję jednak abyśmy od tego momentu pisali kod zupełnie od zera. Dlatego usuń cały kod znajdujący się w tym pliku i zastąp go poniższym, znacznie uproszczonym (to w końcu mają być podstawy ReactJS, więc zacznijmy od czegoś prostego):

import React from 'react';

class AppComponent extends React.Component {
  render() {
    return (
      <div className="main">
        <p>Hello World!</p>
      </div>
    );
  }
}

export default AppComponent;

Wspomniałem wcześniej, że każdy moduł zawierający implementację komponentu ReactJS musi importować moduł react. Dlatego też mamy taki import w pierwszej linii tego pliku.

W kolejnych liniach widać definicję klasy AppComponent, która dziedziczy z React.Component. W ten właśnie sposób tworzy się komponenty ReactJS.

Klasa AppComponent zawiera tylko jedną metodę: render. Metoda ta jest odpowiedzialna za wyświetlenie widoku danego komponentu. W ReactJS, tak jak w powyższym przykładzie, stosuje się notację JSX do definiowania widoków. JSX jest rozszerzeniem składni języka JavaScript, który wygląda podobnie do XML. Dzięki temu możliwe jest definiowanie elementów ReactJS wprost w kodzie metody render.

Na końcu pliku eksportujemy zdefiniowany wcześniej komponent. Słowo default oznacza, że jest to eksport domyślny czyli później, przy imporcie nie musimy używać nawiasów klamrowych

Jeszcze ciekawostka: zwracany element div zawiera atrybut className a nie class! To dlatego, że to tylko wygląda jak zwykły HTML. Tak na prawdę elementy te są odzwierciedleniem, za pomocą składni JSX, czegoś co nazywa się VirtualDOM. A jak już wspomniałem JSX to tylko dodatkowa składnia JavaScript. Nie można więc użyć class w tym miejscu ponieważ jest to zarezerwowane słowo kluczowe…

Druga ciekawostka: metoda render musi zawsze zwracać tylko jeden element JSX. Jeśli więc chciałbyś zwrócić, na przykład, dwa elementy p jeden po drugim to musisz je owinąć w jakiś inny element, na przykład div albo span.

Dygresja: VirtualDOM

Skoro wspomniałem już o VirtualDOM to myślę, że jest to idealny moment na wtrącenie kilku słów na ten temat.

VirtualDOM jest abstrakcją drzewa elementów DOM w HTML czyli, że jest on (VirtualDOM) budowany w oparciu o istniejące drzewo DOM wyświetlane przez przeglądarkę. Dokonując zmiany w komponencie ReactJS, dokonujemy zmiany w VirtualDOM. Na podstawie tych zmian, następuje porównanie VirtualDOM z oryginalnym drzewem. Następnie aktualizowane są tylko te elementy DOM, które tego wymagają.

Dzięki temu wszystkie operacje wykonywane są na swoistej kopii oryginalnego drzewa. Porównanie następuje dopiero po zakończeniu wszystkich zmian. Dzięki temu zmieniane są rzeczywiście tylko te elementy, które na prawdę wymagają aktualizacji. Nie ma po drodze nie potrzebnych, kosztownych zmian w wyświetlanej strukturze.

Uff… Mam nadzieję, że wyjaśniłem to w miarę zrozumiale…

Kolejne komponenty

W sumie miałem pokazać tylko absolutne podstawy ReactJS ale myślę, że warto pokazać Ci jeszcze kilka rzeczy. Generalnie cała “zabawa” z ReactJS opiera się na tworzeniu coraz to nowych komponentów. Jeden komponent zawiera inne komponenty, tamte zawierają kolejne itd. Takie budowanie aplikacji z małych klocków.

Zdefiniujmy więc kolejny komponent w katalogu components (dobra struktura projektu to temat na osobny artykuł). Nazwę go Text.js:

import React from 'react';

class TextComponent extends React.Component {
  render() {
    return (
      <p className="text">Some text</p>
    );
  }
}

export default TextComponent;

Nie ma tutaj w zasadzie nic nowego. Ale nie o to mi chodzi w tym przykładzie. Ciekawsze będzie dla Ciebie to, jak teraz można ten komponent wykorzystać. Wróćmy do pliku src/components/Main.js i zmodyfikujmy go co nieco:

import React from 'react';
import Text from './Text';

class AppComponent extends React.Component {
  render() {
    return (
      <div className="main">
        <Text />
      </div>
    );
  }
}

export default AppComponent;

Na pewno zauważyłeś od razu, że w pliku tym pojawił się nowy import. W ten sposób importuję komponent Text z pliku znajdującego się w tym samym katalogu.

Spójrz teraz na implementację metody render. Zamiast elementu p mamy teraz element Text. Jak więc widzisz, komponenty są po prostu elementami VirtualDOM i możemy je wielokrotnie re-używać w wielu innych komponentach.

Wewnętrzny stan komponentu + data-binding

No dobra, na razie wiesz już jak stworzyć komponent oraz jak użyć go w innym komponencie. Wydaje mi się jednak, że podstawy ReactJS powinny obejmować jeszcze dwie sprawy. Pierwsza z nich to wewnętrzny stan komponentu. Aby to pokazać, zmodyfikujmy co nieco plik src/componets/Main.js:

import React from 'react';
import Text from './Text';

class AppComponent extends React.Component {
  constructor() {
    super();
    this.state = { text: 'Not clicked!' };
  }

  onButtonClick() {
    this.setState({ text: 'Clicked!' });
  }

  render() {
    return (
      <div className="main">
        <Text />
        <p>{this.state.text}</p>
        <button onClick={this.onButtonClick.bind(this)}>Click</button>
      </div>
    );
  }
}

export default AppComponent;

Konstruktor

Na pewno zauważyłeś, że nastąpiło tutaj sporo zmian. Generalnie chodzi o to, że każdy komponent ReactJS może posiadać swój wewnętrzny stan. Na początek zauważ, że do naszego komponentu dodaliśmy konstruktor. W pierwszej jego linii, wywoływana jest funkcja super co powoduje uprzednie wywołanie konstruktora klasy React.Component, z której dziedziczy nasz komponent. Jeśli byśmy go pominęli, dostalibyśmy błąd podczas budowania paczki Webpacka… Bardziej interesująca jest druga linia konstruktora. Poprzez przypisanie do this.state nowego obiektu, powodujemy ustawienie stanu początkowego komponentu.

Jednokierunkowy data-binding

Zróbmy teraz skok do funkcji render. Jak być może zauważyłeś, dodałem do niego element p. Wewnątrz tego taga mamy: {this.state.text}. Nawiasy klamrowe oznaczają, że mamy do czynienia z data-bindingiem. W ReactJS istnieje tylko jednokierunkowy data-binding.

Możesz zapytać: to jak to działa? Spieszę z wyjaśnieniem… ReactJS obserwuje zmiany (zbindowanego) stanu wszystkich komponentów. W przypadku gdy stan danego komponentu się zmieni, następuje ponowne wywołanie metody render danego komponentu (oraz wszystkich komponentów dzieci).

Czyli bardziej obrazowo, na naszym przykładzie: Podczas pierwszego renderowania komponentów, na ekranie wyświetli się tekst “Not clicked!”. Następnie, w jakiś sposób, następuje zmiana wartości this.state.text na “Clicked” (jak to zrobić, z chwilę). Jako, że wartość ta jest zbindowawna do widoku za pomocą nawiasów klamrowych to ReactJS wywoła metodę render raz jeszcze. To spowoduje zmianę w VirtualDOM. Finalnie nastąpi porównanie VirtualDOM z drzewem HTML’a widocznego w przeglądarce. Różnica zostanie wykryta i oryginalne drzewo DOM również się zmieni. Dzięki temu, na ekranie, tekst “Not clicked!” zmieni się na “Clicked!”.

Zmiana stanu

Wspomniałem przed momentem o zmianie wartości this.state.text. Teraz pokażę Ci jak to zrobić. W naszym przykładzie, w metodzie render wyświetlany jest też guzik. Jak możesz zauważyć, posiada on atrybut onClick, za którego pomocą możemy zdefiniować obsługę zdarzenia kliknięcia. Atrybut ten bindujemy do metody this.onButtonClick znajdującej się w tym komponencie. Zauważ, że podczas bindowania atrybutu do metody, wywołuję dodatkowo funkcję bind wskazując kontekst wywołania dla tej metody na this. Jeśli bym tego nie zrobił, ReactJS próbowałby wywołać metodę this.onButtonClick w kontekście elementu button. Z tego powodu dobrą praktyką jest zawsze dodatkowo wywoływać funkcję bind podczas bindowania metody do atrybutu.

No dobra. W powyższy sposób zdefiniowaliśmy sposób obsługi kliknięcia w guzik. Spójrzmy teraz na implementację metody this.onButtonClick. W jej ciele wywoływana jest metoda this.setState odziedziczona z React.Component. Jak parametr przekazujemy jej obiekt, ze zmienionymi wartościami stanu. W ten właśnie sposób należy zmieniać stan obiektu jeżeli chcemy aby jego zmiana wywołała re-render widoku komponentu.

Przekazywanie parametrów, w tym stanu, do komponentu

Ten wpis robi się już trochę przydługi… Opisując jednak podstawy ReactJS nie mogę nie wspomnieć o przekazywaniu parametrów do komponentów. Przejdźmy teraz do pliku src/components/Text.js i zmodyfikujmy go trochę:

import React from 'react';
import PropTypes from 'prop-types';

class TextComponent extends React.Component {
  static propTypes = {
    clickText: PropTypes.string.isRequired,
    staticText: PropTypes.string.isRequired
  };

  render() {
    return (
      <div>
        <p className="text">{this.props.staticText}</p>
        <p className="text">
          {`Text from parent: ${this.props.clickText}`}
        </p>
      </div>
    );
  }
}

export default TextComponent;

Kontrola typów właściwości props

Pierwsza rzecz, na którą należy zwrócić uwagę to to, że oprócz obiektu React importujemy jeszcze obiekt PropTypes (z pakietu prop-types dostępnego w npm - wcześniej była to część pakietu react). Obiekt ten posłuży nam do kontroli typów parametrów przekazywanych do tego komponentu.

Jeśli spojrzysz teraz do implementacji klasy TextComponent to zauważysz, że rozszerzył się on o statyczną zmienną propTypes. Do zmiennej tej przekazujemy obiekt zawierający właściwości odpowiadające nazwami parametrom, które przekazywane są do komponentu. Przypisuję do nich wartości dostarczane przez obiekt PropTypes. Dzięki temu obiektowi mogę nie tylko zdefiniować oczekiwany typ parametru ale także zdecydować czy dany parametr jest wymagany czy też nie.

Bindowanie do parametrów komponentu

Jeśli spojrzysz teraz na implementację metody render to zauważysz dwa elementy p. Ich wnętrze bindowane jest, za pomocą nawiasów klamrowych, do parametrów przekazanych do komponentu. Zwróć uwagę jak dostajemy się do tych parametrów: są one dostępne w obiekcie this.props.

Ktoś mniej zaznajomiony z ES6 może tutaj zadać pytanie o drugi element p. Wykorzystałem tutaj dostępną w ES6 możliwość parametryzowania ciągów znaków. Więcej przeczytasz o tym tutaj.

Przekazywanie parametrów w komponencie-rodzicu

Jedyne co nam teraz pozostaje to przekazać parametry do tak zdefiniowanego komponentu. Zmodyfikujmy więc plik src/components/Main.js:

import React from 'react';
import Text from './Text';

class AppComponent extends React.Component {
  constructor() {
    super();
    this.state = { text: 'Not clicked!' };
  }

  onButtonClick() {
    this.setState({ text: 'Clicked!' });
  }

  render() {
    return (
      <div className="main">
        <Text staticText="Text from child component"
              clickText={this.state.text} />
        <p>{this.state.text}</p>
        <button onClick={this.onButtonClick.bind(this)}>Click</button>
      </div>
    );
  }
}

export default AppComponent;

To co jest tutaj dla nas interesujące to użycie komponentu Text w metodzie render. Jak widzisz doszły nam tutaj dwa parametry: staticText oraz clickText. Odpowiadają one swoimi nazwami atrybutom obiektu propTypes, które zdefiniowaliśmy w komponencie Text.

Do pierwszego z nich przekazujemy po prostu zwykły tekst. Oczywiście równie dobrze mogłaby to być wartość liczbowa lub typu bool. Wtedy musielibyśmy tylko użyć nawiasów klamrowych do ich przekazania.

Drugi parametr jest, jak widzisz, zbindowany do jednej z właściwości stanu naszego komponentu. Dzięki temu, zmiana tego stanu wpłynie również na komponent-dziecko. W końcu wspominałem wcześniej, że kiedy metoda render wywoływana jest po raz kolejny z powodu zmiany stanu, to przy okazji wywoływane są metody render wszystkich jej komponentów-dzieci.

Podstawy ReactJS - podsumowanie

Uff… Szczęśliwie dobrnęliśmy do końca tego wpisu. Ciekawe ilu z Was się to udało…

Mam nadzieję, że przedstawione przeze mnie podstawy ReactJS są dla Was w miarę zrozumiałe i będą dla Was wystarczające do rozpoczęcia przygody z tą świetną biblioteką! Cieszę się niezmiernie, że mogłem o tym w końcu napisać, ponieważ teraz możesz spodziewać się kolejnych wpisów na temat ReactJS. W ten sposób będę chciał dopełnić obrazu całości. Taki też będzie już najbliższy post: napiszę o podziale odpowiedzialności komponentów ReactJS!

Poniżej podaję odnośnik do repozytorium w GitHubie, w którym znajdziesz kod przedstawionej dziś przykładowej aplikacji. Zachęcam do jego przetestowania i samodzielnej z nim “zabawy”!

Kod przykładu zawartego w artykule

Pełen kod przedstawionych dziś przykładów dostępny jest w repozytorium GitHub. Wystarczy, że sklonujesz repozytorium react-introduction-example. Po jego sklonowaniu, nie zapomnij uruchomić npm install w celu zainstalowania wszystkich wymaganych zależności!

A może chciałbyś lepiej poznać Reacta?

Powyższy wpis to tylko niezbędne minimum, które trzeba znać aby zacząć pracować z Reactem. Jeśli chciałbyś dogłębnie i od podstaw poznać tę bibliotekę to specjalnie dla Ciebie przygotowałem specjalne kursy on-line, dzięki którym od podstaw nauczysz się Reacta, ale też Reduxa oraz react-routera! Kliknij poniżej aby dowiedzieć się więcej:

React, Redux, react-router - kursy on-line