Props czyli atrybuty w React.js

Ten wpis jest 4 częścią z 41 w kursie React.js
wp-content/uploads/2017/10/React_logo_wordmark-300x101-1-e1508612391308.png
  1. React.js: Wprowadzenie do kursu od podstaw
  2. Poznaj React.js
  3. Pierwszy komponent w React.js
  4. Props czyli atrybuty w React.js
  5. Podział na komponenty w React.js
  6. Klasy jako komponenty React.js
  7. Interakcja z komponentami React.js
  8. Stan komponentów React.js
  9. State w React.js 2
  10. Metody cyklu życia komponentu w React.js
  11. React.js w przykładach: filtrowanie statycznej listy
  12. Tworzenie aplikacji React.js dzięki create-react-app
  13. React.js na GitHub Pages dzięki create-react-app
  14. Testowanie aplikacji React.js — podstawy Enzyme
  15. Testowanie React.js w Enzyme — props, state i interakcje
  16. Poprawne bindowanie funkcji w React.js
  17. Odpowiadam na pytania: Babel, ECMAScript, destrukturyzacja, onClick, className
  18. Komunikacja pomiędzy komponentami w React.js
  19. Komunikacja z API w React.js
  20. Formularze w React.js — kontrolowane komponenty
  21. Formularze w React.js — niekontrolowane komponenty
  22. Odpowiadam na pytania: props, nawiasy klamrowe, funkcje vs klasy, import react
  23. TDD w React.js z pomocą react-testing-library
  24. Flux i Redux: globalny store i jednokierunkowy przepływ danych
  25. React + Redux — kurs: wprowadzenie i podstawy
  26. React + Redux — filtrowanie listy, proste selektory
  27. Projektowanie komponentów: Presentational & Container Components
  28. Asynchroniczność w Redux: redux-thunk
  29. Kiedy używać state, a kiedy Redux?
  30. Nowe metody cyklu życia: getDerivedStateFromProps i getSnapshotBeforeUpdate
  31. Leniwe ładowanie komponentów w React dzięki import
  32. Higher Order Reducers — Redux i powtarzanie kodu
  33. React Hooks — wprowadzenie i motywacja
  34. React Hooks: useState, czyli stan w komponentach funkcyjnych
  35. React Hooks: useState — wiele stanów, callbacki i inne niuanse
  36. React Hooks: useEffect — efekty uboczne w komponencie
  37. React Hooks a żądania do API
  38. useReducer — przenoszenie logiki poza komponent
  39. useMemo, useCallback, czyli rozwiązanie problemów ze zmieniającymi się propsami
  40. Wady React Hooks
  41. React Hooks: Piszemy własne hooki!

W tej części nauczysz się parametryzować komponenty w React.js. Poznasz pojęcie „props” oraz dowiesz się do czego one (te „propsy”) służą.

To co zrobiliśmy do tej pory było spoko, ale przecież nie będziesz tworzyć nowego komponentu zawsze gdy będziesz chciał(a) wyświetlić inny tekst w aplikacji, prawda? Wyobraź sobie, że masz do zaprojektowania popup, w którym będzie wyświetlony tytuł oraz tekst. Za moment to zaimplementujemy!

Projekt

Zacznijmy od zaprojektowania kodu takiego modala. Będzie to dosłownie kilka prostych linii HTML:

<div>
  <dialog open>
    <h1>Tytuł</h1>
    <p>Treść</p>
  </dialog>
</div>

Nic skomplikowanego. dialog to element wbudowany w HTML5. Następnie zamieniamy taki kod na komponent, czyli tworzymy funkcję, która zwraca JSX:

function MojKomponent() {
  return (
    <div>
      <dialog open>
        <h1>Tytuł</h1>
        <p>Treść</p>
      </dialog>
    </div>
  );
}

Tym sposobem Twoim oczom powinien się ukazać taki oto piękny efekt:

Kurs React.js – komponent bez props

Props w React.js

Niestety teraz aby zmienić tekst, musimy edytować kod samego komponentu, a to jest mało praktyczne. Czy można jakoś sparametryzować to co wyświetla komponent? Tak! Używając tzw. propsów 🙂

Do tej pory komponentu używaliśmy w taki sposób: <MojKomponent />. Czyli jest to tak jakby element. A czy możemy dodać tutaj jakieś atrybuty? Właśnie tak! To dokładnie będą nasze propsy. Props to atrybut. Podajmy więc tytuł i treść: <MojKomponent title="Tytuł" content="Treść" />. Czy to już? Niestety nie. Teraz musimy jeszcze jakoś się odwołać do tych propsów i wyświetlić.

Propsy to argumenty

Propsy do komponentów przekazywane są po prostu jako argumenty. A konkretnie: Jeden argument, który jest obiektem. Czy mogłoby być prościej? Chyba nie 🙂 Funkcja przybiera taką postać:

function MojKomponent({ title, content }) { … }

Wyświetlanie

Jak teraz wyświetlić zawartość takiej zmiennej w JSX? Jest to również bardzo proste. Wystarczy skorzystać ze składni {nazwa} — i to wszystko!

Ostatecznie otrzymujemy taki kod:

function MojKomponent({ title, content }) {
  return (
    <div>
      <dialog open>
        <h1>{title}</h1>
        <p>{content}</p>
      </dialog>
    </div>
  );
}

Ostateczny efekt

Teraz już nie pozostaje nic innego jak wyrenderować ten komponent. Podobnie jak dotychczas:

ReactDOM.render(
  <MojKomponent
    title="I co, duma?"
    content="To było prostsze niż by się mogło wydawać, prawda?"
  />,
  document.getElementById("app")
);

Domyślne propsy

Co się wydarzy gdy nie podasz jakiegoś propsa i spróbujesz go wyświetlić? Na szczęście nic złego. Zostanie potraktowany jak pusty string "" i nic się nie pokaże. Lepsze to niż wyświetlenie użytkownikom np. undefined, prawda? 🙂 Ale na pewno nie idealne! Właśnie dlatego możemy podać domyślne propsy.

Najprościej możesz to zrobić korzystając ze składni ES2015, z której już i tak korzystamy 🙂 Do argumentów można dopisać domyślne wartości. Po znaku = po prostu podajemy stringa, który ma się wyświetlić gdy danego atrybutu na komponencie nie ma:

function MojKomponent({ title = "Modal", content }) { // tutaj podajemy domyślne propsy
  return (
    <div>
      <dialog open>
        <h1>{title}</h1>
        <p>{content}</p>
      </dialog>
    </div>
  );
}

Teraz przy próbie wyrenderowania <MojKomponent /> zamiast tytułu pokaże się napis „Modal”, a w miejsce treści nie pokaże się nic (pusty element <p>).

Demo

See the Pen Props czyli atrybuty w React.js by Michał Miszczyszyn (@mmiszy) on CodePen.

Co dalej?

Poznaj React w dwa dni na szkoleniu z Type of Web!

W kolejnej części nauczysz się jak dzielić aplikację na komponenty. Rozpoczniesz też budowę „prawdziwej” aplikacji! Jeśli chcesz na bieżąco śledzić kolejne części kursu React.js to koniecznie śledź mnie na Facebooku i zapisz się na newsletter.

Nie wysyłamy spamu, tylko wartościowe informacje. W każdej chwili możesz się wypisać klikając „wypisz się” w stopce maila.

Ćwiczenie

Ćwiczenie: Zrób eksperyment z propsami. Spróbuj przekazać zamiast stringa kolejno: liczbę, obiekt, tablicę i funkcję. Co można z nimi zrobić? Czy da się przekazać tam HTML? Napisz w komentarzu!

Nawigacja po kursie:
  1. React.js: Wprowadzenie do kursu od podstaw
  2. Poznaj React.js
  3. Pierwszy komponent w React.js
  4. Props czyli atrybuty w React.js
  5. Podział na komponenty w React.js
  6. Klasy jako komponenty React.js
  7. Interakcja z komponentami React.js
  8. Stan komponentów React.js
  9. State w React.js 2
  10. Metody cyklu życia komponentu w React.js
  11. React.js w przykładach: filtrowanie statycznej listy
  12. Tworzenie aplikacji React.js dzięki create-react-app
  13. React.js na GitHub Pages dzięki create-react-app
  14. Testowanie aplikacji React.js — podstawy Enzyme
  15. Testowanie React.js w Enzyme — props, state i interakcje
  16. Poprawne bindowanie funkcji w React.js
  17. Odpowiadam na pytania: Babel, ECMAScript, destrukturyzacja, onClick, className
  18. Komunikacja pomiędzy komponentami w React.js
  19. Komunikacja z API w React.js
  20. Formularze w React.js — kontrolowane komponenty
  21. Formularze w React.js — niekontrolowane komponenty
  22. Odpowiadam na pytania: props, nawiasy klamrowe, funkcje vs klasy, import react
  23. TDD w React.js z pomocą react-testing-library
  24. Flux i Redux: globalny store i jednokierunkowy przepływ danych
  25. React + Redux — kurs: wprowadzenie i podstawy
  26. React + Redux — filtrowanie listy, proste selektory
  27. Projektowanie komponentów: Presentational & Container Components
  28. Asynchroniczność w Redux: redux-thunk
  29. Kiedy używać state, a kiedy Redux?
  30. Nowe metody cyklu życia: getDerivedStateFromProps i getSnapshotBeforeUpdate
  31. Leniwe ładowanie komponentów w React dzięki import
  32. Higher Order Reducers — Redux i powtarzanie kodu
  33. React Hooks — wprowadzenie i motywacja
  34. React Hooks: useState, czyli stan w komponentach funkcyjnych
  35. React Hooks: useState — wiele stanów, callbacki i inne niuanse
  36. React Hooks: useEffect — efekty uboczne w komponencie
  37. React Hooks a żądania do API
  38. useReducer — przenoszenie logiki poza komponent
  39. useMemo, useCallback, czyli rozwiązanie problemów ze zmieniającymi się propsami
  40. Wady React Hooks
  41. React Hooks: Piszemy własne hooki!

Nie wysyłamy spamu, tylko wartościowe informacje. W każdej chwili możesz się wypisać klikając „wypisz się” w stopce maila.

Subscribe
Powiadom o
guest
34 komentarzy
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Tomasz Sochacki
2 lat temu

Fajnie, że działasz krok po kroku, wiele osób na pewno zyska na tym blogu. Może warto jeszcze tylko wtrącić gdzieś zdanko, że używasz destrukturyzacji obiektu props tworząc komponent. W wielu poradnikach widywałem zapisy „( props ) => { … }”. Osobiście skłaniam się ku Twojej wersji i sam również notorycznie korzystam z dobrodziejstwa destrukturyzacji ale nie wszyscy mogą wiedzieć co tu się dzieje i będą mieć problem też inne poradniki 🙂 Pozdrawiam, i powodzenia w react-blogowaniu 🙂 Im więcej o React w PL tym lepiej dla polskiego front-endu 🙂

Marcin Rudzki
Marcin Rudzki
2 lat temu

Z tym przekazywaniem HTML, to jest trochę problem. Z poniższych wersji zadziała tylko ta trzecia, tj. linia nr 30 na screenie: comment image
Stackoverflow wspomina też o dangerouslySetInnerHTML. Czy są jeszcze inne możliwości przekazania HTML przez props? Jaki sposób polecasz?

Kasia
Kasia
3 miesięcy temu

Podaję HTML jako defaultowa wartość title i mi normalnie wstrzyknęło HTML, a nie ciąg znaków także chyba jakieś zmiany nastąpiły.

Kamil Mirosz
Kamil Mirosz
1 rok temu

Wszystko działa oprócz htmla 🙂 zwróciło mi to jako string, nie mogłem przekazać objektu np {person} ale {person.name} już działa 🙂
Gdzieś w komentarzach pojawiło się coś takiego prop={ {key: val} } Ale totalnie tego nie rozumiem 🙂

Rafał Sikora
Rafał Sikora
1 rok temu

Generalnie kursik ok i niema problemu by go zrozumieć .. jednak nie do końca łapię jak to jest z tymi props, skoro wprowadzasz obiekt {}, zapis niepowinien być { key : val } ? coś mi umyka?

PiotrPo
1 rok temu

Można przekazać wszystko, jeżeli props jest w cudzysłowach traktowany jest jako string, w przypadku klamr jako funkcja, objekt lub zmienna.

Joanna Trapp
Joanna Trapp
1 rok temu

Ćwiczenie wykonane, wyświetla się cała tablica, obiekt cały nie chce się wyświetlić. Nie pokazuje tagów HTML, od razu wykonany kod.

Piotr Siekierzyński
Piotr Siekierzyński
1 rok temu

Nie za bardzo rozumiem, czemu działa:

zaś nie działa:

Tomeek
Tomeek
1 rok temu

Mam problem nie działa mi program i nie mam za bardzo pomysłu przez co. Tu wklejam kod:

Tomeek
Tomeek
1 rok temu

Uncaught Invariant Violation: Target container is not a DOM element.
at invariant (https://unpkg.com/react-dom@16.8.1/umd/react-dom.development.js:49:15)
at Object.render (https://unpkg.com/react-dom@16.8.1/umd/react-dom.development.js:20747:36)
at :27:10
at run ( Wojtek Urbański.26.0/babel.js:61531:11" rel="nofollow ugc">https://unpkg.com/babel-standaloneAvatar Wojtek Urbański.26.0/babel.js:61531:11)
at check ( Wojtek Urbański.26.0/babel.js:61597:10" rel="nofollow ugc">https://unpkg.com/babel-standaloneAvatar Wojtek Urbański.26.0/babel.js:61597:10)
at loadScripts ( Wojtek Urbański.26.0/babel.js:61638:4" rel="nofollow ugc">https://unpkg.com/babel-standaloneAvatar Wojtek Urbański.26.0/babel.js:61638:4)
at runScripts ( Wojtek Urbański.26.0/babel.js:61668:4" rel="nofollow ugc">https://unpkg.com/babel-standaloneAvatar Wojtek Urbański.26.0/babel.js:61668:4)
at transformScriptTags ( Wojtek Urbański.26.0/babel.js:336:40" rel="nofollow ugc">https://unpkg.com/babel-standaloneAvatar Wojtek Urbański.26.0/babel.js:336:40)
at  Wojtek Urbański.26.0/babel.js:327:13" rel="nofollow ugc">https://unpkg.com/babel-standaloneAvatar Wojtek Urbański.26.0/babel.js:327:13

Tomeek
Tomeek
1 rok temu

Dobra dzięki za pomoc właśnie zauważyłem że w id miałem literówkę.

Tomeek
Tomeek
1 rok temu
Kamil
Kamil
1 rok temu

Cześć,

Podzielę się swoimi obserwacjami, bo albo czegoś nie rozumiem, albo jest niedostatecznie wytłumaczone.

Chcąc zamienić Twój przykład:

< MojKomponent title="I co, duma?" />

… na np. liczbę, robię tak:

< MojKomponent title=666 />

To nie działa, muszę użyć title={666}, prawda? Dlaczego?

PS: właśnie zauważyłem że Disqus automatycznie modyfikuje tagi, m.in. robi LowerCase, a dla atrybutów (props) dodaje cudzysłów jeśli go pominę. Dlatego użyłem spacji przed MojKomponent.

damian
damian
1 rok temu

Dziwne rzeczy,
Bez problemu podałem < H2 markup={} />,
w render() return Sep: {this.props.markup};
I śmiga HTML

Patrycja Bąk
Patrycja Bąk
10 miesięcy temu

Wygląda na to, że wszystko jest przekazywane jako string, w przypadku arraya, obiektu wyciągane są wartości 🙂 Funkcja nie pokazała się

Paweł Kołodziejczak
Paweł Kołodziejczak
8 miesięcy temu

W dzisiejszych czasach dynamiczne renderowanie DOM w native JS to banał, reaktywny DOM możemy tworzyć przy pomocy template strings + pułapek Proxy (jest też dostępny pdolyfill dla IE11 :)) w załączniku screen kodu React vs Native JS skoro nie widać różnicy to po co pobierać 70+ kb biblioteki i uczyć się obsługi frameworka który suma summarum indywidualną składnię i docelowo parsuje w natywnym silniku JS wbudowanym w przeglądarce.

Paweł Kołodziejczak
Paweł Kołodziejczak
8 miesięcy temu

Oh dear, przeczytaj ponownie ze zrozumieniem – na co komu spam?

Paweł Kołodziejczak
Paweł Kołodziejczak
8 miesięcy temu

Renderowanie DOM + aktualizacja tagu „p” w zależności od wpisania tekstu w wygląda tak:

Funkcje pomocnicze „render” oraz „observe”:

Podobnie jak w znanych frameworkach możesz stworzyć jeden wielki JSON z setką parametrów, tworzysz jedną pułapkę na cały object i wszystkie parametry są aktualizowane w zależności od funkcji callback.

Oczywiście to zajście prosta, strukturalna implementacja. W projektach wszystko funkcjonuje w osobnych modułach ES6 aby zachować odpowiednią estetykę i nie pisać pojedynczych skryptów z milionem linii kodu (coś ala komponenty w React ;]). Posiadam też własną klasę ok 119 linijek kodu która bez pułapek proxy obserwuje zmiany w DOM’ie w czasie rzeczywistym wykorzystując parametry data-prop – działanie identyczne jak props i computed props w React lub Vue.