Miniatura artykułu

React - kompozycja komponentów

8 minut

Skopiuj link

Data publikacji: 12/29/2023, 7:12:08

Ostatnia aktualizacja: 4/1/2024

Komponenty i ich kompozycja (ang. composition) to nieodłączna część niemal każdego front-endowego frameworka. Jeżeli w swoim życiu napisałeś chociaż jedną aplikację z wykorzystaniem np. Reacta, to prawdopodobnie skorzystałeś już z kompozycji.

Jednak świadome jej użycie to sztuka, dlatego w tym artykule dowiesz się, co dokładnie kryje się pod tym terminem, zrozumiesz jak zastosować ją w praktyce, a także dowiesz się jakie problemy rozwiązuje.

Co to jest kompozycja

Kompozycja, to po prostu sposób w jaki tworzymy, a następnie łączymy w większe struktury nasze komponenty.

Choć to zdanie może brzmieć, jak coś oczywistego, a wręcz banalnego (kto z nas nie tworzył wcześniej komponentów?), to w praktyce nie jest to aż tak proste, jak się wydaje.

Problem związany z błędną strukturą komponentów zostaje najczęściej uwidoczniony dopiero w momencie, gdy aplikacja rozrasta się, jednak wprowadzenie zmian na tym etapie jest czasochłonne, dlatego warto zadbać o to już od samego początku projektu.

Żeby jednak móc to zrobić, trzeba wiedzieć na co zwracać uwagę i czego się wystrzegać.

Jak zastosować kompozycję

Zacznijmy od stworzenia prostej aplikacji, która będzie posiadać jeden formularz, a wewnątrz niego znajdą się dwa pola tekstowe oraz przycisk służący do wysyłania.

Pierwszy krok, to utworzenie wymaganych komponentów

Stwórzmy jeszcze jeden komponent, który będzie odpowiedzialny, za przechowywanie stanu, oraz wyświetlenie komponentu Form. W naszym przypadku będzie to jednocześnie głównym komponent aplikacji - stąd jego nazwa App.

Na pierwszy rzut oka, wszystko wydaje się być w porządku. App przechowuje stan formularza (używamy do tego hooka useState), funkcję odpowiedzialną za jego wysyłanie, oraz stan przycisku (jeżeli formularz nie jest wypełniony, to przycisk jest zablokowany).

Następnie wszystkie te wartości są przekazywane dalej, do Form, który odpowiada za wyświetlenie komponentu Input, oraz Button, w związku z tym przesyła dalej otrzymane od App propsy.

Przepływ propsów przez poszczególne komponenty

Przepływ propsów przez poszczególne komponenty

W tym momencie powinna się zapalić w głowie czerwona lampka. Zanim wszystkie wymagane wartości trafią do komponentów Input i Button, muszą przejść przez Form, który z nich nie korzysta. Jest to zatem zbędny krok, którego pozbędziemy się stosując odpowiednią kompozycję.

Taka sytuacja zdarza się bardzo często, a liczba komponentów, przez które przesyłane są wartości, by ostatecznie trafić do miejsca docelowego potrafi być znacznie większa. Zjawisko to określane jest jako props drilling i jest jedną z największych bolączek aplikacji utworzonych z użyciem nowoczesnych frameworków frontendowych (nie tylko React cierpi na tą przypadłość).

Naszym celem jest zachowanie wszystkich trzech komponentów - co prawda Form w tym przypadku jest jedynie kontenerem (komponent odpowiadający za wyświetlanie innych komponentów) i moglibyśmy go usunąć bez większych problemów, jednak w realnym projekcie z pewnością nie będzie to takie proste. Dlatego zamiast usuwać, zmienimy jedynie podejście, a przy okazji zwiększymy reużywalność kodu.

Na początek zmienimy komponent Form. Zamiast wyświetlać zawsze te same komponenty (tak, jak to ma miejsce wyżej), będzie przyjmować children, a następnie wyświetli je.

Czas dostosować App. Jedyne co musimy zrobić, to przekazać do komponentu Form tagi, które powinien wyświetlić.

Dzięki zmianie w strukturze komponentów uniknęliśmy dodatkowego kroku podczas przesyłania propsów.

Oczywiście przykład, który przedstawiłem jest trywialny, ale jego zadaniem nie jest przedstawienie jak najbardziej skomplikowanego kodu. Zamiast tego powinien zachęcić Cię do pochylenia się nad podejściem, które stosujesz w pracy, pisząc kod dla siebie i w każdej innej sytuacji.

Na koniec pozostało już tylko uporządkować wiedzę, którą powinieneś wynieść z tego artykułu:

  • Struktura komponentów w nowoczesnej aplikacji lub stronie internetowej ma bardzo duże znaczenie. Prawidłowo utworzona pozwoli uniknąć problemów w przyszłości, gdy projekt się rozrośnie.

  • Powinieneś unikać przesyłania propsów przez wiele komponentów, jeżeli nie są w nich wykorzystywane. Poprawienie kompozycji potrafi rozwiązać wiele takich sytuacji - nie zawsze trzeba stosować Reduxa 😄 (lub inne zewnętrzne biblioteki).

  • Odpowiednia kompozycja pozytywnie wpływa na reużywalność (ang. reusability) komponentów. Stają się bardziej generyczne, a ich zawartość może być dostosowana do naszych potrzeb.

  • Wydajność Twojej aplikacji może wzrosnąć w przypadku świadomego wykorzystania kompozycji - jeżeli propsy przekazywane do komponentów dzieci (w naszym przypadku jest to Input i Button) nie ulegną zmianie, to ponowny render rodzica (Form) nie spowoduje ponownego renderu dzieci.

Ostatni punkt omówimy na przykładzie. Ponownie wrócimy do tworzonej wcześniej aplikacji, jednak tym razem komponent Form wygląda następująco (pozostałe komponenty nie uległy zmianie):

Jak widzisz dodałem do niego stan, którego jedynym celem jest wywołanie ponownego renderu komponentu. Cofnąłem także zmiany związane z kompozycją, więc wszystkie komponenty znów są w środku.

Jeżeli nacisnę teraz przycisk Rerender, to stan ulegnie zmianie, a Form zostanie ponownie wyrenderowany. Ważny jest fakt, że dotyczy to również wszystkich komponentów dzieci, które są w nim użyte (Input i Button).

Sytuacja wygląda zupełnie inaczej w przypadku zmiany kompozycji. Zastosujemy identyczne podejście jak poprzednim razem:

Pozostało już tylko wykorzystać poprawiony komponent Form:

Tym razem, gdy naciśniemy przycisk Rerender, ani Input, ani Button nie zostaną ponownie wyrenderowane. W tym przypadku wydajność naszej aplikacji niemal nie uległa zmianie, ponieważ jej kod jest bardzo prosty, jednak warto mieć na uwadze, że w większych aplikacjach, taka zmiana może przynieść znacznie większe efekty.

Podsumowanie

Jak wspomniałem na samym początku, świadome stosowanie kompozycji, to potężne narzędzie, które powinieneś stosować w każdej aplikacji internetowej od samego początku jej istnienia.

Warto poświęcić chwilę i zastanowić się nad układem komponentów, a po skończonym zadaniu jeszcze raz zweryfikować, czy nie można wprowadzić zmian, które usprawnią działanie, lub poprawią czytelność kodu (ten proces można nazwać self code review 😛)

Koniecznie sprawdź, czy w którymś ze swoich projektów nie popełniłeś błędów, o których wspominałem, a jeżeli tak, to popraw je w ramach treningu.

Avatar: Wojciech Rygorowicz

Software Engineer / Fullstack developer

Wojciech Rygorowicz

wojciech.rygorowicz@gmail.com

Podziel się na

Dodaj komentarz

Komentarze (0)

Brak komentarzy