React.js to obecnie najbardziej popularny framework Javascript. To właśnie jego wybiera wielu początkujących Frontend Developerów między innymi z powodu niskiego progu wejścia.
Mimo to nie wszystkie rzeczy są jasne i oczywiste, dlatego często popełniamy proste błędy, które mogą mieć negatywny wpływ na działanie aplikacji.
Poniżej znajdziesz 6 najczęściej popełnianych błędów, których rozwiązanie natychmist poprawi zarówno jakość, jak i performance Twojej aplikacji.
Zagnieżdżone komponenty
Jest to dość często spotykany błąd, który ma znaczący wpływ na performance aplikacji React.js.
Spójrz na poniższy kod:
const Component = () => {
const childComponent = () => {
return <h1>Hello world!</h1>
}
return (
<div>
<childComponent />
</div>
);
}
Z jednej strony mogłoby się wydawać, że skoro nasz childComponent jest wykorzystywany tylko w Component, to dlaczego nie moglibyśmy deklarować go właśnie w tym miejscu?
Problem polega na tym, że z każdym wywołaniem (renderowaniem) Component będziemy na nowo deklarowali childComponent.
Co prawda, jeśli popełnimy ten błąd w jednym komponencie, to najprawdopodobniej nie będzie to miało większego znaczenia, jednak jeśli będziemy go powielali wszędzie, nasza aplikacja znacznie straci na performensie.
Najlepszym rozwiązaniem tego problemu będzie wyciągnięcie każdego z komponentów do osobnych plików pamiętając o najlepszych praktykach, jeśli chodzi o strukturę projektu.
Używanie index jako key
W React renderowanie elementów w pętli odbywa się za pomocą metody array.map().
Kto z nas nie spotkał się z błędem, który ostrzegał, że każdy element renderowany w ten sposób musi zawierać atrybut "key"?
Wydawać by się mogło, że skorzystanie z wbudowanego indeksu array.map pasuje tutaj idealnie, czyż nie?
Atrybut "key" używany jest przez React do zrozumienia, kiedy element jest dodawany, zmieniany lub usuwany. Ma ona działać jako unikalny identyfikator każdego z nich, a nie jako zwykły index w ramach listy.
Choć może się wydawać, że w naszym przykładzie użyty index faktycznie działa jako identyfikator, zastanów się, co by się stało, gdybyśmy dodali więcej elementów do listy, ale nie na jej końcu.
W tym przypadku wychodzi na to, że jeden indeks byłby przypisany do dwóch różnych elementów, co prawda nie jednocześnie, ale w dalszym ciągu jest to błąd.
Rozwiązaniem tej sytuacji byłoby oczywiście dodanie identyfikatora, bądź jeśli jest to tekst i masz pewność, że zawsze będzie unikalny możesz śmiał go użyć.
Prop drilling
Wyobraź sobie, komponent Parent, który ma własny stan. Musimy go przekazać do komponentu Child znajdującego się kilka poziomów niżej.
Parent -> Component 1 -> Component 2 -> Child
Często spotykamy się z problemem, które właśnie nazywamy Prop drilling. Polega on na tym, że przekazujemy daną wartość do propsów każdego z dzieci, aby w końcu dotarła do finalnego komponentu.
Nie jest to błąd, który znacząco wpłynie na aplikację, jednak jest to często popełniany anty-patern. Nie powinniśmy przekazywać propsów, z których dany komponent nie korzysta.
W naszym przypadku zarówno Component 1, jak i Component 2 będą jedynie przekazywać go w dół i to wszystko.
Do rozwiązania tego problemu używamy Context API, które pozwoli nam przekazać tą wartość do finalnego komponentu bez angażowania pozostałych komponentów. Więcej informacji na temat Context API znajdziesz tutaj.
Używanie useState zbyt często
useState jest podstawą podstaw pracy z React.js, w którym możemy przechowywać stan danego komponentu.
Jest to świetny hook, który wykorzystujemy często, jednak niekiedy zbyt często.
Przykładowym błędem jest na przykład dodawanie do useState rzeczy, które łatwo jesteśmy w stanie obliczyć/uzyskać z istniejącego już stanu.
W moim wypadku mogłaby to być na przykład ilość wyświetleń wszystkich postów.
Skoro w stanie przechowuję listę artykułów wraz z wyświetleniami każdego z nich łatwo mogę obliczyć sumę wyświetleń za pomocą prostej pętli. Przechowywanie tej wartości w useState byłoby zwykłym nadużyciem.
Najlepiej jest zadać sobie pytanie, czy możemy uzyskać potrzebne dane z istniejących już stanów - jeśli tak, to nie ma potrzeby dodać kolejnego :)
Długie komponenty / dużo logiki
Mógłbym ten problem opisać tak naprawdę jako dwie osobne rzeczy, jednak jak dłużej o tym pomyślałem wszystko sprowadza się do jednego rozwiązania.
Kiedyś jeden z moich kolegów z pracy udzielił mi świetnej rady na temat tworzenia komponentów. Powinniśmy stworzyć osobne komponenty z:
- wszystkich powtarzalnych elementów (wszystko, co wrzucamy do array.map)
- każdej sekcji/funckjonalności
Było to w momencie, gdy zobaczył, że komopnent strony głównej jednego z projektów nad którym pracowałem miał ponad 1 000 linijek.
Skorzystałem z jego rady i ilość kodu zmalała o 70%.
Rzeczy, które zauważyłem natychmiast były:
- znacznie lepsza czytelność kodu
- o wiele łatwiej było mi zrozumieć co dana część kodu robi
- gdy po czasie wróciłem do projektu znacznie łatwiej było mi się w nim odnaleźć
Niby prosta rzecz, a zmienia naprawdę wiele.
Niepotrzebne divy
Na koniec mało istotny błąd, jednak można go w prosty sposób naprawić.
Podczas zwracania JSX musimy pamiętać, aby był oplecione tylko jednym elementem.
Wiele osób niczym się nie przejmując dodaje tam pustego diva, na przykład w ten sposób:
return(
<div>
<span />
<span />
</div>
);
Jeśli w każdym komponencie wykonamy ten zabieg finalnie okarze się, że nasz DOM to zlepek divów, co po pierwsze wygląda nieprofesjonalnie, a po drugie może powodować problemy ze stylowaniem w niektórych przypadkach.
Rozwiązanie jest banalnie proste - React.Fragment - czyli tak naprawdę pusty element, którym możemy opleć pozostałe elementy w naszym komponencie:
return(
<>
<span />
<span />
</>
);
W DOM wyrenderuje się samo:
<span />
<span />
Podsumowanie
Wiele z powyższych błędów popełniamy notorycznie, jednak na początku nauki zdarza się to każdemu.
Sam potrzebowałem czasu, aby nauczyć się je naprawiać i mam nadzieję, że Ty też teraz nie będziesz miał z nimi żadnego problemu.
Jeśli dopiero zaczynasz naukę React.js polecam Ci mój artykuł, w którym przedstawiam 9 Rzeczy, Które Musisz Wiedzieć Zanim Zaczniesz Uczyć Się React.js.