O mocnych i słabych stronach ReactJS
React.js to biblioteka JavaScriptowa (tak – biblioteka, a nie framework jak często można usłyszeć), używana do budowania interfejsów (z ang. User Interface, w skrócie UI), a więc wszystkiego, co pozwala na interakcję użytkowników z maszynami. Interfejsy znajdziemy wszędzie, od aplikacji mobilnych, poprzez strony internetowe, kończąc na ekspresie do kawy.
W przypadku biblioteki React, potrzeba naprawdę okazała się matką wynalazku, ponieważ powstała w odpowiedzi na problem, przed którym stanął Facebook. Tamtejsi inżynierowie szukali sposobu na budowanie dynamicznych, a jednocześnie wysoce wydajnych interfejsów, w wyniku czego powstał ReactJS. Pierwotnie przeznaczony jedynie do projektów wewnętrznych, w 2013 roku został udostępniony przez Facebooka na zasadach open-source. Biblioteka ta, dzięki swojemu rewolucyjnemu podejściu do budowania UI, zrobiła furorę wśród programistów.
Otwierając tegoroczną ankietę serwisu stackoverflow.com, zobaczymy, że ReactJS pojawia się na pierwszym miejscu zarówno w rankingach najbardziej lubianych, jak i najbardziej pożądanych technologii internetowych.
Zdj. 1. Lista najbardziej lubianych technologii internetowych (źródło: insights.stackoverflow.com)
Zdj. 2. Lista najbardziej pożądanych technologii internetowych (źródło: insights.stackoverflow.com)
Spis treści
Zalety
1. Niski próg wejścia
React cechuje się stosunkowo niskim progiem wejścia i znając jakkolwiek język JavaScript, możliwe jest przejście w krótkim czasie od posiadania zerowej wiedzy na temat biblioteki, do pracy nad konkretnym projektem przy jej pomocy. W przeciwieństwie choćby do Angulara, który wymaga od dewelopera przyswojenia niemałej wiedzy przed postawieniem pierwszego kroku, na drodze rozwoju w React nie napotkamy wielkich przepaści. Naukę tej technologii można przyrównać do wędrówki po górskiej drodze – miewamy trudności, których pokonanie kosztuje nas trochę wysiłku, wciąż jednak stawiamy kolejne kroki i idziemy naprzód. Kiedy po pewnym czasie przystaniemy i spojrzymy za siebie, ujrzymy naprawdę satysfakcjonujący widok.
Pomimo że szlifowanie umiejętności w dalszej pracy z React wymaga dużego zaangażowania i wytrwałości, to na początku naszej wędrówki nie czujemy się tak przytłoczeni ilością informacji, które musimy przyswoić. Może okazać się to dużym plusem, patrząc z perspektywy naszej motywacji do pracy. Przyjemnie jest czuć, że wciąż robimy postępy, bo dzięki temu nie tracimy ciekawości i chęci do dalszych starań. W końcu najtrudniej jest postawić ten pierwszy krok.
2. Dojrzałość i stabilność
React niewątpliwie jest biblioteką dojrzałą i zaprawioną w bojach. Pieczę nad nią sprawuje Facebook, a korzysta z niej (co znaczy, że i ufa jej możliwościom) wiele dużych firm. Także w Ericsson sprawdziła się ona podczas tworzenia wielu interfejsów, na których działaniu i wydajności można polegać. Omawiana biblioteka zgromadziła wokół siebie jedną z największych społeczności związanych z dziedziną technologii internetowych, a co za tym idzie, ma ogromne wsparcie w przypadku jakichkolwiek problemów bądź pytań. Trudno będzie znaleźć problem, którego rozwiązanie nie zostało do tej pory opisane w serwisach takich jak stackoverflow. Patrząc na aktualne wyniki statystyk, które zostały zamieszczone na początku artykułu, możemy być spokojni o przyszłość tej biblioteki, a co za tym idzie, również o jej wsparcie i rozwój.
3. Jednokierunkowy przepływ danych
Jednokierunkowy przepływ danych w React nie jest pojęciem unikatowym, jednakże w przypadku technologii internetowych jest czymś wyjątkowym. Dla React znaczy on tyle, że:
- Stan komponentu jest przesyłany do jego widoku oraz komponentów dziedziczących.
- Akcja może zostać wywołana poprzez interakcję z widokiem (np. poprzez kliknięcie).
- Wywołana akcja może zmienić stan komponentu.
- Zmiana w stanie komponentu jest przesyłana do jego widoku oraz komponentów dziedziczących.
Diagram 1. Jednokierunkowy przepływ danych w React
Widok komponentu wynika z jego stanu. Stan komponentu może zostać zmieniony jedynie poprzez wywołanie danej akcji. Akcja powoduje zmianę stanu. Krąg się zamyka.
Dzięki temu aplikacja jest:
- mniej podatna na błędy, ponieważ posiadamy większą kontrolę nad przepływem danych,
- łatwiejsza w debugowaniu, ponieważ wiemy, co przychodzi skąd,
- bardziej wydajna, ponieważ powiązania między elementami interfejsu są jasno określone.
Jednokierunkowy przepływ danych w React wpływa pozytywnie także na przejrzystość powiązań między komponentami, co może okazać się pomocne np. podczas analizowania wydajności aplikacji. Skoro do stanu komponentu dostęp ma jedynie on sam, to wszelkie zmiany dotkną jedynie jego samego oraz komponenty po nim dziedziczące – nigdy jego „rodzica”, bądź „rodzeństwa” w strukturze DOM. Można to zobrazować, korzystając z prostego diagramu. Na czerwono zaznaczone zostały komponenty, w których stanie zaszły zmiany.
Diagram 2. Zmiana stanu komponentów
Zmiany te spowodują przeładowanie jedynie tych elementów interfejsu, które na poniższym diagramie zostały zaznaczone kolorem.
Diagram 3. Wyniki zmian stanu
4. Bezbolesne SEO
W przypadku jakiegokolwiek biznesu internetowego optymalizacja strony pod kątem wyszukiwarek jest kluczowa, jednakże wiele JavaScript’owych frameworków ma problem w radzeniu sobie z tym zadaniem. React znacząco skraca czas potrzebny na załadowanie się strony, dzięki swojej lekkości oraz szybszemu renderowaniu, co z kolei jest jednym z kryteriów, na które zwraca uwagę algorytm indeksujący strony, używany przez Google.
5. Open-source
React jest projektem typu open-source, co oznacza tyle, że każdy może dorzucić swoje trzy grosze do jego tworzenia. Jeśli spojrzymy na stronę React w serwisie github, to zobaczymy, że w jego rozwoju bezpośrednio wzięło udział ponad 1300 deweloperów. Świadczy to o tym, że społeczność zgromadzona wokół biblioteki jest naprawdę duża – dla porównania, nad rozwojem dwóch konkurencyjnych frameworków, Angular i Vue, łącznie pracowała mniejsza ilość osób.
Dzięki temu, że React cieszy się tak dużym zainteresowaniem, nietrudno znaleźć w internecie rozwiązania przeróżnych problemów, z którymi może przyjść nam się zmierzyć, czy też inspiracji potrzebnej przy rozwoju własnego projektu.
6. Nowoczesna aplikacja internetowa w pojedynczej komendzie
Kolejną rzeczą, za którą można pokochać pracę z React to możliwość przygotowania i od razu konfiguracji nowego projektu za pomocą jednej komendy. Wystarczy otworzyć konsolę, napisać:
npx create-react-app my-app cd my-app npm start
Kod 1. komendy startowe create-react-app
Gotowe[1] – aplikacja wystartowała, a my możemy kodować. Ucieszą się z tego szczególnie osoby, które nie lubią grzebania w plikach konfiguracyjnych oraz początkujący programiści, którzy w danym momencie zwyczajnie nie potrafią tego zrobić. Drużyna facebooka zadbała już o takie kwestie, jak konfiguracja modułu pakującego (Webpack), wsparcie nowoczesnej składni JavaScriptu (Babel), kontrola jakości kodu (ESLint), środowisko testowe i wiele, wiele więcej (pełną listę można znaleźć tutaj). Zadbała także o możliwość używania bieżących wersji wymienionych modułów, dzięki czemu wraz z aktualizacją create-react-app mamy zapewnioną najświeższą wersję pozostałych pakietów.
Co więcej, jeśli podczas pracy nad projektem zapragniemy dokonać zmian w jego konfiguracji tak, aby lepiej spełniał nasze spersonalizowane wymagania, to nikt nam tego nie zabroni – ponownie, wystarczy pojedyncza komenda, żeby uzyskać dostęp do wszystkich plików konfiguracyjnych. Voilà.
7. Virtual DOM
Kiedy strona internetowa zostaje załadowana, przeglądarka internetowa tworzy jej model obiektowy (z ang. Document Object Model, w skrócie DOM). Za pomocą JavaScriptu możemy, korzystając z tego modelu, wyszukiwać interesujące nas elementy, a następnie zmieniać ich właściwości, dzięki czemu nasza strona staje się dynamiczna. Tutaj pojawia się jednak pewien problem (który w dodatku rośnie wraz z rozmiarem projektu) – przeglądanie dużych modeli DOM w poszukiwaniu danych elementów wymaga dużej ilości obliczeń ze strony przeglądarki.
Co więcej, zmiana choćby jednego z elementów naszego modelu powoduje przeładowanie całego drzewa HTML. Ma to duży wpływ na wydajność strony, a co za tym idzie, na interakcje z użytkownikiem i w konsekwencji jego poziom zadowolenia. W takich przypadkach z pomocą przychodzi React – tworzy on wirtualną reprezentację drzewa HTML, tzw. Virtual DOM, którą później przechowuje w pamięci. Za każdym razem, kiedy zmienia się stan aplikacji, React nie musi ładować od nowa całego drzewa HTML. Zamiast tego generuje wyłącznie jego wirtualną reprezentację, którą porównuje ze stanem wcześniejszym (zachowanym w pamięci), a następnie zmienia w DOM’ie jedynie te elementy, które tego wymagają.
Dzięki takiemu podejściu nie tylko zyskujemy na wydajności, lecz także mamy możliwość przeładowywania interfejsu w czasie rzeczywistym (tzw. hot reloading). Kiedy deweloper wprowadza zmiany w kodzie, widok automatycznie zostaje przeładowany, co sprawia, że praca z ReactJS jest zarazem efektywna i bardzo przyjemna. Jeśli spośród wszystkich zalet React byłbym zmuszony wybrać tylko jedną, postawiłbym na Virtual DOM!
8. Reużywalne komponenty
Praca z React w dużej mierze polega na tworzeniu UI z tzw. komponentów. Nazywamy w ten sposób elementy interfejsu, które spełniają określoną funkcję (np. przycisk). Podobnie jak z połączonych ze sobą w odpowiedni sposób klocków powstaje wieża, czy samochód, tak poprzez łączenie ze sobą drobnych komponentów można budować bardziej złożone elementy, z których następnie powstaje interfejs.
Zdj. 1. Klocki jako analogia komponentów w ReactJS (źródło: atomicdesign.bradfrost.com)
Dla przykładu przyjmijmy, że chcemy stworzyć podstawowe menu zawierające w sobie trzy identyczne przyciski (tak wiem, nie jest to do końca życiowy przykład, ale chodzi w nim głównie o przekazanie pewnej idei). Zacznijmy od stworzenia jednego z takich przycisków. W uproszczonej wersji mógłby on wyglądać choćby tak:
const MyButton = () => { return <div> <button>Click me! </button> </div> }
Kod 1. Komponent – MyButton
Dzięki wspomnianej reużywalności raz stworzonych komponentów nie musimy zapisywać tego kodu trzykrotnie, żeby stworzyć 3 przyciski – wystarczy, że w komponencie służącym za menu wkleimy MyButton w sposób zaprezentowany poniżej.
const MyMenu = () => { return <div> <h1>Not that useful menu </h1> <MyButton /> <MyButton /> <MyButton /> </div> }
Kod 2. Komponent – MyMenu
To, co czyni reużywalność wspaniałym rozwiązaniem, to fakt, że takich gotowych, raz stworzonych komponentów można używać do woli, gdzie tylko się chce, a zaoszczędzony na powtarzalnej pracy czas wykorzystać przy zadaniach, które stanowią większe wyzwanie. Z kolei dzięki niezależności komponentów internet wręcz kipi od pojedynczych komponentów, którymi dzielą się programiści, oraz całych frameworków gotowych do użycia (np. Material-UI, czy React Bootstrap). Podejście to jest także wyjątkowo przydatne w przypadku, kiedy zależy nam na zachowaniu konsekwencji w designie naszej aplikacji, lub (tym bardziej) pomiędzy większą ilością produktów przez nas dostarczanych. W Ericsson zależy nam na tej spójności, a możliwość dzielenia się raz stworzonymi komponentami pomiędzy różnymi aplikacjami znacznie ułatwia to zadanie.
9. React Native
Dzięki React Native znając ReactJS, można pisać aplikacje mobilne na iOS i Android. Pomimo że kod napisany jest w języku JavaScript, twoja aplikacja używa tego samego natywnego API, co pozostałe aplikacje mobilne. Między React a React Native znajdziemy oczywiście drobne różnice, jednak główne zasady działania są zachowane, a to oznacza, że mamy po swojej stronie wszystkie mocne strony JavaScriptu i ReactJS. Wygląda na to, że powoli zbliżamy się do momentu wyczekiwanego przez wielu programistów, w którym dzięki poznaniu jednej technologii możliwe stanie się tworzenie aplikacji na wszystkich platformach.
Wady
1. Architektura
Pisałem wcześniej o zalecie React, jaką jest niski próg wejścia w rozpoczęciu z nim pracy. Trzeba jednak pamiętać, że wolność ta niesie ze sobą pewną odpowiedzialność. Podczas pracy z tą biblioteką mamy pełną swobodę działania i podejmowania decyzji, m.in. w sprawach architektury. Oznacza to jednak, że również odpowiedzialność za to zadanie spoczywa tylko i wyłącznie na naszych barkach.
React jest w końcu jedynie biblioteką, a nie pełnym frameworkiem, jak to wygląda w przypadku choćby Angulara. Jeśli przyrównalibyśmy go do w pełni wyposażonej kuchni, posiadającej mnóstwo narzędzi, zbiór przepisów, których trzeba dokładnie przestrzegać i gotowy zestaw przypraw, React byłby pokojem z dobrej jakości kuchenką, zestawem porządnych garnków i mnóstwem wolnego miejsca do swobodnego zagospodarowania wedle uznania szefa kuchni, który z niej będzie korzystać.
Angular niesie ze sobą zbiór reguł dotyczących tego, jak ma wyglądać struktura twojej aplikacji i „na dzień dobry” rozwiązuje problemy typu „jakiej biblioteki powinienem użyć do routingu?” – najzwyczajniej narzuca swoje zdanie, do którego programista musi się ustosunkować, czy mu się to podoba, czy nie. Fakt ten sprawia, że mamy mniejszą kontrolę nad projektem, jednakże i odpowiedzialność za podejmowanie decyzji w tej materii jest mniejsza.
2. JSX
W React używamy składni JSX, która jest rozszerzeniem składni JavaScriptu, pewnego rodzaju hybrydą dającą możliwość używania w kodzie znaczników HTML. Pomimo że fragment JSX wygląda na pierwszy rzut oka jak kod HTML, to pozwala on w pełni korzystać z mocy JavaScriptu. Rzućmy okiem na poniższy przykład:
const greeting = <h1 className="greeting">Hello, my friend! </h1>
Kod 3. Przykład kodu JSX
Fragment kodu, który przypisany został do zmiennej greeting, pozornie nie różni się niczym od tradycyjnego nagłówka HTML (z wyjątkiem atrybutu className, który jest swoistym wyjątkiem, a pełni rolę klasycznego atrybutu class w składni HTML). W rzeczywistości jest to wyrażenie JavaScriptowe, które zostanie przekompilowane do obiektu postaci:
var greeting = React.createElement( "h1", { className: "greeting" }, "Hello, my friend! uD83DuDD90" );
Kod 4. Skompilowany kod JSX
To podejście niewątpliwie kryje w sobie wiele zalet (choćby ochronę przed iniekcjami), jednakże dla niektórych przyzwyczajenie się do JSX może okazać się wyzwaniem.
3. Zawrotna prędkość rozwoju biblioteki
Po raz kolejny uwagę przyciąga rewers facebookowej monety – fakt, iż React cały czas dynamicznie się rozwija to niewątpliwa zaleta, jednakże nadążanie za ciągłymi zmianami może okazać się problematyczne dla osób z ograniczoną ilością czasu. Nie każdy też ma ochotę na cykliczne odnawianie swojej wiedzy i uczenie się od nowa rzeczy, które już potrafił, a teraz wyglądają i działają zupełnie inaczej.
4. Biblioteki dodatkowe
Założeniem ReactJS jest robienie niewielkiej ilości rzeczy, ale robienie ich naprawdę dobrze – dzięki temu biblioteka sama w sobie jest stosunkowo lekka. Podczas rozwijania realnych projektów, prawie na pewno będziemy musieli skorzystać z bibliotek dodatkowych, których jest całe mnóstwo. Oznacza to tyle, że jeżeli ktoś lubi mieć wszystkie narzędzia od razu pod ręką, bez potrzeby szukania dalej, może czuć się rozczarowany.
W końcu używanie bibliotek dodatkowych rodzi wiele pytań, na które trzeba sobie odpowiedzieć – przykładowo, dlaczego w tym projekcie akurat biblioteka A będzie lepsza od biblioteki B? Taka sytuacja daje nam dużą niezależność, jednocześnie zadanie to okazuje się nieraz czasochłonne, a do tego nikt nam nie zagwarantuje, że pomimo podjętego wysiłku zawsze podejmiemy dobrą decyzję.
Podsumowanie
React niesie ze sobą wiele korzyści takich jak reużywalność komponentów, virtual DOM, jednokierunkowy przepływ danych, lekkość i stabilność, niski próg wejścia, create-react-app, łatwość w przerzuceniu się na aplikacje mobilne z React Native, a także wszystkie zalety, jakie daje projekt open-source i język JavaScript. Musimy jednak pamiętać o tym, że nie każdemu od razu spodoba się składnia JSX, prędkość zmieniania się biblioteki, fakt, iż sam będzie musiał zmierzyć się z architekturą projektu czy też z potrzebą szukania bibliotek dodatkowych do wykorzystania.
Za pomocą React i React Native powstały takie aplikacje jak Facebook, Instagram, Netflix, Airbnb, Pinterest, czy też Skype, a także całe mnóstwo mniejszych aplikacji, oraz narzędzi używanych wewnętrznie. W Ericsson biblioteka ta okazała się bardzo przydatna m.in. przy stworzeniu narzędzia pozwalającego na wizualizację różnych procesów i zbiorów danych, które użytkownik (korzystając w interfejsu) mógł dopasować do własnych potrzeb.
Fakt, że tak wiele znaczących firm zaufało tej bibliotece, nastraja nas w stosunku do niej pozytywnie, jednakże to my sami musimy ocenić, które technologie najlepiej wpiszą się w nasze oczekiwania. Pozostaje nam działać.
[1] Aby powyższe komendy zadziałały będziemy potrzebować zainstalowanego Node’a w wersji 8.16.0, 10.16.0, lub nowszej.
Zdjęcie główne artykułu pochodzi z unsplash.com.