Diversity w polskim IT
Iskander Samatov
Iskander SamatovSenior Software Engineer @ HubSpot

7 złych praktyk w React

Przedstawiamy praktyczne porady, dzięki którym korzystanie z Reacta stanie się po prostu lepsze!
20.12.20215 min
7 złych praktyk w React

Oto niektóre ze złych praktyk najczęściej spotykanych w aplikacjach React i porady, jak sobie z nimi poradzić. Jeśli nie nauczysz się ich rozpoznawać i zapobiegać na wczesnym etapie, twoja baza kodu stanie się koszmarem.

Robienie wszystkiego przez Redux

Redux jest genialny! W tle optymalizuje wydajność i pozwala nam w łatwy sposób uzyskać wgląd w ogólny stan aplikacji.

Problem polega na tym, że gdy nowi programiści poznają Reduksa, zaczynają używać go jak magicznej różdżki, która rozwiązuje wszystkie problemy.

Takie podejście ma kilka wad:

  • Twój kod traci intencje. Jeśli wszystko jest w Redux, nie jest jasne, czy twój kod ma mieć zasięg lokalny czy globalny. Wprowadzanie zmian jest trudniejsze, ponieważ masz mniejszą pewność co do części aplikacji, na które będą one miały wpływ.
  • Wydajność ulega pogorszeniu, gdy używasz Reduxa do częstych zdarzeń, takich jak śledzenie wejścia formularza. Ponieważ Redux wpływa na globalny stan aplikacji, gwarantowane jest, że spowoduje więcej ponownych renderowań.

Praktyczna zasada: Używaj Reduxa tylko dla prawdziwie globalnych danych, takich jak sesja użytkownika lub motyw aplikacji. Dla wszystkiego innego lepiej tworzyć konteksty dla konkretnych części aplikacji.

Przechowywanie wszystkiego jako stanu

Innym problemem, który napotykają nowi programiści, jest niewykorzystanie koncepcji stanu pochodnego.

Wiele zmiennych może być obliczanych w locie. Przykładowo, powiedzmy, że masz tablicę elementów typu checkbox. Nie musisz przechowywać checkedCount w stanie. Możesz wyprowadzić checkedCount, przechodząc przez tablicę elementów i odfiltrowując te sprawdzone przy każdym renderowaniu.

Praktyczna zasada: Przed zapisaniem zmiennej w stanie należy zadać sobie pytanie: Czy mogę jakoś wyprowadzić tę zmienną na podstawie innych danych, które już przechowuję?”

Przekazywanie propsów za pomocą używania wszędzie operatora spread

Zauważyłem, że ta sztuczka jest często używana w aplikacjach w React.

Przekazujesz propsy do komponentu-dziecka za pomocą {...props}. Wygląda to schludnie i może Ci się wydawać, że kod jest przez to bardziej wartościowy. Ale prawda jest taka, że z czasem twój kod będzie mniej przewidywalny i trudniejszy do zrozumienia.

Kiedy zaczynasz przekazywać propsy, używając wszędzie operatora spread, nie jest od razu jasne, które propsy są faktycznie potrzebne komponentom dziedziczącym atrybuty. A wtedy refaktoryzacja staje się prawie niemożliwa, nawet małe wysiłki refaktoryzacyjne otworzą puszkę Pandory. Dodatkowo znacznie trudniej jest śledzić bugi w drzewie komponentów.

Praktyczna zasada: Generalnie unikaj przekazywania propsów za pomocą operatora spread. Jednym z przypadków, kiedy jest to uzasadnione, jest pisanie container component lub HOC, który renderuje i ulepsza swoje komponenty potomne.

Deklarowanie komponentów wewnątrz komponentów

Deklarowanie komponentu wewnątrz innego wygląda tak:

Pisanie komponentów wewnątrz komponentu nadrzędnego jest złym pomysłem z dwóch powodów:

  • Twój kod staje się ściśle wewnętrznie zależny. Twój wewnętrzny komponent staje się zależny od zakresu domknięcia komponentu nadrzędnego.
  • Spada wydajność. Komponent nadrzędny będzie ponownie tworzył funkcję deklaracji komponentu potomnego przy każdym renderowaniu.

Praktyczna zasada: Unikaj deklarowania komponentów wewnątrz komponentu nadrzędnego.

Przekazywanie zbyt wielu informacji do komponentów

Dobrze jest być oszczędnym, jeśli chodzi o to, jak wiele informujesz o swoich komponentach. Staraj się pamiętać o oddzieleniu komponentów inteligentnych od prezentacyjnych, kiedy decydujesz, ile danych przekazać.

Komponenty prezentacyjne są komponentami, które wyświetlają wyłącznie HTML. Nie mają one własnego stanu i nie obsługują żadnej logiki zachowawczej.

Komponenty inteligentne zazwyczaj utrzymują stan i dostarczają dane oraz zachowanie komponentom prezentacyjnym poprzez wykonywanie żądań API, mutowanie w redux itp.

W przypadku komponentów prezentacyjnych powinieneś przekazywać tylko dane niezbędne do renderowania. Komponenty prezentacyjne nie powinny decydować czy renderować swoją zawartość. Zamiast tego logika powinna być obsługiwana przez inteligentne komponenty.

Na przykład, spójrz na ten kod:

Podczas inspekcji komponentu nadrzędnego, nie jest jasne, że nasz komponent dziedziczący posiada logikę renderowania warunkowego. Możemy wyjaśnić ten kod poprzez przywrócenie logiki warunkowej i pozwolenie naszemu komponentowi nadrzędnemu na decydowanie, czy renderować jego potomstwo.

Jeśli to możliwe, przekazuj tylko prymitywy do komponentów prezentacyjnych. Ułatwia to późniejszą optymalizację wydajności. 

Powiedzmy, że przekazujesz cały obiekt user w ten sposób:

Zamiast tego możesz przekazać imię, nazwisko i datę:

Dzięki temu łatwiej jest zredukować liczbę ponownego renderowania za pomocą React.memo. Powodem jest to, że React porównuje propsy obiektów dzięki odniesieniu, podczas gdy prymitywy są porównywane ze względu na wartość.

Podsumowując, oto problemy związane z przekazywaniem zbyt wielu informacji do komponentów:

  • Trudniej odróżnić komponenty inteligentne od prezentacyjnych. Podstawowa logika Twojej aplikacji powinna być obsługiwana przez komponenty inteligentne, podczas gdy komponenty prezentacyjne powinny jedynie wyświetlać HTML.
  • Pogarsza się wydajność. Jeśli przekażesz zbyt wiele propsów do komponentu, będzie on renderował się za każdym razem, gdy te propsy się zmienią, co spowoduje nadmiarowe ponowne renderowanie.

Nadmierna optymalizacja wydajności

Czasami programiści zaczynają optymalizować swój kod, zanim pojawi się jakikolwiek realny problem. Jest to zła praktyka z dwóch prostych powodów:

  • Skomplikowany i „przeinżynierowany” kod. Próba rozwiązania problemu, zanim on zaistnieje, jest najpewniejszym sposobem na nadmierne skomplikowanie kodu.
  • Zmarnowany czas. Zamiast tego mógłbyś stworzyć nowe funkcje i rozwiązywać problemy, które mają znaczenie.

Z mojego doświadczenia mogę powiedzieć, że inteligentne rozdzielenie komponentów inteligentnych i prezentacyjnych rozwiązuje ~90% problemów z wydajnością w aplikacjach w React.

Ogromne drzewa komponentów

Ostatnim, ale nie mniej ważnym elementem są ogromne drzewa komponentów.

Zwykle problem ten pojawia się, gdy nie poświęcisz czasu na właściwe oddzielenie logicznych i prezentacyjnych części kodu.

Spójrz na ten komponent:

Okropne, prawda? Bardzo trudno jest rozszyfrować, co się tutaj dzieje. Mamy kilka obszarów do poprawy:

  • Refaktoryzacja długich instrukcji warunkowych na osobne zmienne.
  • Rozdzielenie części drzewa na mniejsze elementy prezentacyjne.
  • Przesunięcie funkcji strzałek poza drzewo komponentów.

Zastosujmy to i zobaczmy, jak teraz wygląda komponent:

To drzewo komponentów wygląda teraz o wiele lepiej.

Praktyczna zasada: Utrzymuj drzewa komponentów w czystości, aby łatwiej było zobaczyć, co i kiedy ma być renderowane.

Wnioski

W tym artykule opisałem 7 złych praktyk w React i pokazałem, dlaczego nie warto ich stosować. Unikając tych praktyk od samego początku, nie będziesz musiał spędzać dużo czasu na refaktoryzacji swojego kodu w przyszłości. Sprawdź mój post, aby dowiedzieć się więcej: wskazówki dotyczące pisania czystego kodu w React.

Oryginał tekstu w języku angielskim można przeczytać tutaj.

<p>Loading...</p>