Jakiś czas temu pojawiła się nowa wersja Reacta oznaczona numerkiem 16.2.0. Oprócz poprawek, wprowadza ona nową składnię dla czegoś co nazywane jest przez twórców Fragmentami. I dzisiaj krótko lecz treściwie o tym właśnie.
Na początku był pewien problem…
Wyobraźmy sobie, że nasza przykładowa aplikacja w Reakcie składa się z nagłówka, tekstu i stopki. I teraz chcielibyśmy sobie te elementy wyrenderować do elementu o identyfikatorze #app
. Otóż bez dodatkowego elementu „opakowującego” pozostałe, ta sztuka się nie uda. Nie jest to oczywiście problem tylko Reacta, bo z tego co pamiętam już nawet Backbone.js się z tym borykał, ale to temat na zupełnie inną dyskusję. Wyobraźmy więc sobie następującą funkcję render:
render() { return ( <div> {/* konieczny div, którego byśmy nie chcieli */} <header>Przykładowa apka</header> <p>Przykładowy tekst</p> <footer>Taka prosta stopka</footer> </div> ); }
Może być ona częścią komponentu o nazwie… np. App, następnie chcemy ten komponent wyrenderować do wskazanego przez nas elementu:
ReactDOM.render(<App />, document.querySelector('#app'));
Wszystko fajnie, ale czy możemy się jakoś obejść bez tego nieszczęsnego, zbędnego elementu?
… a potem pojawiło się rozwiązanie!
React w wersji 16, oprócz znaczących zmian pod maską, wprowadził wspomniane w tytule fragmenty. Jest to specjalna notacja tablicowa, z pomocą której możemy pozbyć się dodatkowych elementów opakowujących ciało komponentu. Spójrzmy na poprzedni przykład, uzupełniony o składnię tablicową:
render() { return ( [ <header key="1">Przykładowa apka</header>, <p key="2">Przykładowy tekst</p>, <footer key="3">Taka prosta stopka</footer>, ]; ); }
I dzięki temu sposobowi zapisu pozbyliśmy się niepotrzebnego elementu. Jednak nie nazwałbym tej składni czymś wspaniałym. Skoro zwracamy tablicę to należy pamiętać, że każdy element musi posiadać atrybut key i musi być oddzielony przecinkiem. Przy małej ilości elementów nie jest to straszliwy ból, ale wyobraźmy sobie jak to może wyglądać przy większej ilości węzłów.
Nowa składnia fragmentów – czyli da się jeszcze lepiej!
Składnia tablicowa pozwala nam pominąć zbędny element opakowujący, ale nie jest ona zbyt wygodna. Na szczęście od wersji 16.2 Reacta jesteśmy już w stanie zaimportować element Fragment
, dzięki któremu składnia praktycznie zostanie niezmieniona w stosunku do pierwszego przykładu, a my pozbędziemy się dodatkowego elementu. Spójrzmy jak to wygląda w praktyce:
import { Fragment } from "react"; ... render() { return ( <Fragment> <header>Przykładowa apka</header> <p>Przykładowy tekst</p> <footer>Taka prosta stopka</footer> </Fragment> ); }
Znacznie lepiej prawda? Nie różni się to praktycznie niczym innym jak tylko zastąpieniem elementu opakowującego wspomnianym już wielokrotnie fragmentem. Istnieje jeszcze prostsza składnia, która pozwala pominąć słówko Fragment, a wygląda ona w ten sposób:
render() { return ( <> <header>Przykładowa apka</header> <p>Przykładowy tekst</p> <footer>Taka prosta stopka</footer> </> ); }
Na pierwszy rzut oka to przeoczenie nazwy elementu HTML, ale wygląda całkiem uroczo ^^. Za pomocą „pseudo elementu” <>
i </>
jesteśmy w stanie uzyskać ten sam rezultat co w przypadku skorzystania z elementu Fragment. Bomba! 🙂
Podsumowanie
Fragmenty w React pozwalają na pominięcie dodatkowego elementu opakowującego ciało komponentu i dzięki banalnej składni z pewnością znajdą swoich fanów. Dzięki nim będziemy w stanie np. wyrzucać kilka komórek tablicy z jednego komponentu, czy też w wygodny sposób renderować elementy znacznika listy definicji (<df>
). Elementy listy definicji składają się ze znacznika nazwy terminu <dt>
i objaśnienia terminu <dd>
. Bez fragmentów składanie takiej listy z podwójnych elementów jest po prostu smutne 😉