Wprowadzenie React #2 (2020) – komponenty i props

W poprzednim wpisie utworzyliśmy nasz projekt oraz pierwszy komponent, w tym będziemy dalej bawić się komponentami oraz dowiemy się czym są w React props.

Drzewo komponentów

Nasza galeria zdjęć z jednym tylko zdjęciem nie do końca zasługuje na to miano. Przydałoby się więc dodać jeszcze kilka obrazów. Możemy to zrobić powielając komponent <Image>… jednak jak ma się to przedstawiać w funkcji ReactDOM.render?

W ReactJS jeśli chcemy stworzyć kilka równorzędnych komponentów wówczas musimy je opakować w jakiś komponent nadrzędny. Możemy zrobić na przykład tak:

export const Image = () => (
  <img
    src="https://images.unsplash.com/photo-1508138221679-760a23a2285b"
    height="175"
    width="200"
  ></img>
);

export const App = () => {
  return (
    <div>
      <Image />
      <Image />
      <Image />
      <Image />
      <Image />
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));

Stworzyliśmy dodatkowy, główny, komponent App, który ma w sobie jeden węzeł nadrzędny – ‘div‘ oraz pięć komponentów Image. Przy okazji ustawiliśmy na sztywno wysokość i szerokość obrazu w komponencie Image by nie był tak gigantyczny.

Natomiast dodawanie ‘sztucznego’ diva o ile przy tworzeniu nowych aplikacji zdaje się relatywnie bezbolesne to w momencie, kiedy np. migrujemy istniejącą aplikację na React, a nasze testy bazują na X-Path… wtedy taki niegroźny div, jest źródłem wielu zmian w kodzie.

Dlatego jakiś czas temu do Reacta dodano React.Fragment, który zbiera w węzeł nadrzędny komponenty (jak div w przykładzie) na potrzeby Reacta. Nie ma on jednak przełożenia na ostateczny wygląd HTML, czyli po prostu go nie widać.

export const App = () => {
  return (
    <React.Fragment>
      <Image />
      <Image />
      <Image />
      <Image />
      <Image />
    </React.Fragment>
  );
};

Możemy ten kod jeszcze odrobinę skrócić i zamiast React.Fragment możemy napisać po prostu <>.

export const App = () => {
  return (
    <>
      <Image />
      <Image />
      <Image />
      <Image />
      <Image />
    </>
  );
};

React props

Wszystko fajnie tylko po co nam 5 takich samych obrazków? Jeśli chcemy mieć inny URL dla zdjęcia musimy tworzyć nowy komponent? Na szczęście nie. Tu pojawiają się propsy, dzięki, którym komponent Image będzie mógł wyświetlać różne obrazy.

Tak jak standardowe tagi HTML mogą mieć pewne właściwości (jak height i width w tagu img), tak komponenty Reactowe również mogą mieć zdefiniowane przez nas właściwości.

Konkretnie do komponentu Image możemy dodać property “url”, który będzie wskazywać na adres obrazu.

export const App = () => {
  return (
    <>
      <Image url="https://images.unsplash.com/photo-1508138221679-760a23a2285b" />
      <Image url="https://images.unsplash.com/photo-1474487548417-781cb71495f3" />
      <Image url="https://images.unsplash.com/photo-1580109672851-b85640868813" />
      <Image url="https://images.unsplash.com/photo-1580046939256-c377c5b099f1" />
      <Image url="https://images.unsplash.com/photo-1576801488695-2e4d7a14b8b5" />
    </>
  );
};

By dobrać się do tego pola, z poziomu komponentu Image, musimy nieco go rozbudować.

export const Image = props => {
  console.log(props.url);
  return <img src={props.url} height="175" width="200"></img>;
};

Po pierwsze teraz nasza funkcja tworząca komponent bierze jeden argument – props. Jest to obiekt, który ma zestaw pól odpowiadającym właściwością, jakie zostały przesłane do naszego komponentu. W naszym wypadku obiekt props ma pole url, bo zrobiliśmy tak <Image url=”https://images.unsplash.com/photo-1576801488695-2e4d7a14b8b5″ />. Nie ma natomiast propsa ala czy kot bo żaden taki klucz nie został przesłany.

Teraz by odnieść się do wartości przesłanej z poziomu kodu JavaScript używamy standardowo props.url, natomiast jeśli chcemy użyć tej wartości w elemencie zwracanym, czyli w JSX, musimy opakować ją w nawiasy klamrowe {props.url}.

Często w komponentach, zamiast ciągle pisać props. dokonuję się destrukturyzacji parametru funkcji. Wygląda to wówczas tak:

export const Image = ({ url }) => {
  console.log(url);
  return <img src={url} height="175" width="200"></img>;
};

Zapis {url} oznacza “weź pole url z obiektu, który zostanie przesłany jako parametr tej funkcji i przypisz je do zmiennej url, wyrzuć wszystko inne”. Gdybyśmy mieli więcej interesujących nas pól destrukturyzacja wyglądałaby tak: {url, otherField, anotherField }.

I to by było na tyle jeśli chodzi o podstawy pracy z props. W następnej części zajmiemy się nasłuchiwaniem na zdarzenia i reagowaniem na nie.

Kod przykładu dostępny jest na Github.

Tradycyjnie zapraszam do dołączenia do newslettera, gdzie materiały odnośnie React również mają swoje miejsce.

Praktyczne wprowadzenie do ReactJS 2020 | #1

React jest jedną z najpopularniejszych bibliotek języka Javascript, służącą do tworzenia interfejsów użytkownika, a konkretniej tych webowych, czyli stron internetowych. Został on stworzony  w podziemiach tajnej fabryki Facebooka ;), inne duże korporacje, jakie z niego korzystają to PayPal czy Netflix. Na chwilę obecną można śmiało powiedzieć, ze React stał się dominującą biblioteką w ekosystemie JS. Wprowadzenie React JS utworzymy, krok po kroku, pierwszą, pełnoprawną aplikację internetową. Czytaj dalej Praktyczne wprowadzenie do ReactJS 2020 | #1