Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds

Props i ich zastosowanie

Props (skrót od "properties", czyli właściwości) są fundamentalnym mechanizmem przekazywania danych między komponentami w React. Możesz myśleć o nich jak o argumentach funkcji - pozwalają na wprowadzanie danych do komponentu z zewnątrz.

Podstawy props

Props są przekazywane do komponentu jako pojedynczy obiekt. W komponentach funkcyjnych, ten obiekt jest zwykle pierwszym parametrem funkcji:

1function MissionInfo(props) {
2  return (
3    <div className="mission-info">
4      <h2>{props.name}</h2>
5      <p>Status: {props.status}</p>
6      <p>Rozpoczęcie: {props.startDate}</p>
7    </div>
8  );
9}
10
11// Użycie
12<MissionInfo 
13  name="Apollo 11" 
14  status="Zakończona" 
15  startDate="16 lipca 1969" 
16/>

Przekazywanie danych między komponentami

Jedną z największych zalet React jest możliwość tworzenia złożonych interfejsów poprzez komponowanie mniejszych, wielokrotnego użytku komponentów. Props są kluczowe w tym procesie, ponieważ umożliwiają komunikację między tymi komponentami.

Przekazywanie props w dół (z rodzica do dziecka)

Najczęstszym kierunkiem przepływu danych w React jest z góry na dół - od komponentów rodzicielskich do komponentów potomnych:

1function SpaceProgram() {
2  const missionData = {
3    id: 'apollo11',
4    name: 'Apollo 11',
5    crew: ['Neil Armstrong', 'Buzz Aldrin', 'Michael Collins'],
6    launchDate: '16 lipca 1969',
7    status: 'Zakończona'
8  };
9  
10  return (
11    <div className="space-program">
12      <h1>Program Kosmiczny</h1>
13      <Mission 
14        name={missionData.name}
15        crew={missionData.crew}
16        launchDate={missionData.launchDate}
17        status={missionData.status}
18      />
19    </div>
20  );
21}
22
23function Mission({ name, crew, launchDate, status }) {
24  return (
25    <div className="mission">
26      <h2>{name}</h2>
27      <p>Data startu: {launchDate}</p>
28      <p>Status: {status}</p>
29      <CrewList crew={crew} />
30    </div>
31  );
32}
33
34function CrewList({ crew }) {
35  return (
36    <div className="crew-list">
37      <h3>Załoga:</h3>
38      <ul>
39        {crew.map((member, index) => (
40          <li key={index}>{member}</li>
41        ))}
42      </ul>
43    </div>
44  );
45}

W tym przykładzie:

  1. Komponent
    SpaceProgram
    zawiera dane misji
  2. Dane są przekazywane jako props do komponentu
    Mission
  3. Mission
    przekazuje dodatkowo tablicę
    crew
    do komponentu
    CrewList

Destrukturyzacja props

Zamiast korzystać z

props.nazwa
, w nowoczesnym JavaScript powszechnie stosuje się destrukturyzację, co czyni kod bardziej czytelnym:

1// Zamiast:
2function Astronaut(props) {
3  return (
4    <div>
5      <h3>{props.name}</h3>
6      <p>Rola: {props.role}</p>
7      <p>Misje: {props.missions}</p>
8    </div>
9  );
10}
11
12// Lepiej:
13function Astronaut({ name, role, missions }) {
14  return (
15    <div>
16      <h3>{name}</h3>
17      <p>Rola: {role}</p>
18      <p>Misje: {missions}</p>
19    </div>
20  );
21}

PropTypes i walidacja danych

PropTypes to system do sprawdzania typów props podczas rozwoju aplikacji. Pomaga wyłapywać błędy związane z przekazywaniem nieprawidłowych danych do komponentów.

1import PropTypes from 'prop-types';
2
3function LaunchButton({ onClick, isEnabled, label }) {
4  return (
5    <button 
6      onClick={onClick}
7      disabled={!isEnabled}
8      className="launch-button"
9    >
10      {label || 'Start'}
11    </button>
12  );
13}
14
15LaunchButton.propTypes = {
16  onClick: PropTypes.func.isRequired,
17  isEnabled: PropTypes.bool,
18  label: PropTypes.string
19};
20
21LaunchButton.defaultProps = {
22  isEnabled: true
23};

Dostępne są różne typy walidatorów:

  • PropTypes.array: Tablica
  • PropTypes.bool: Wartość boolowska
  • PropTypes.func: Funkcja
  • PropTypes.number: Liczba
  • PropTypes.object: Obiekt
  • PropTypes.string: String
  • PropTypes.symbol: Symbol
  • PropTypes.node: Cokolwiek, co może być renderowane (liczby, stringi, elementy, tablica)
  • PropTypes.element: Element React
  • PropTypes.instanceOf(Class): Instancja klasy
  • PropTypes.oneOf(['News', 'Photos']): Jedna z wielu wartości
  • PropTypes.oneOfType([PropTypes.string, PropTypes.number]): Jeden z wielu typów
  • PropTypes.arrayOf(PropTypes.number): Tablica określonego typu
  • PropTypes.objectOf(PropTypes.number): Obiekt z wartościami określonego typu
  • PropTypes.shape({ name: PropTypes.string, age: PropTypes.number }): Obiekt określonego kształtu
  • PropTypes.exact({ name: PropTypes.string }): Obiekt dokładnie określonego kształtu

Domyślne wartości props

Możesz ustawić domyślne wartości dla props na wypadek, gdyby nie zostały przekazane:

1function Countdown({ seconds, color }) {
2  return (
3    <div style={{ color }}>
4      T-minus: {seconds} sekund
5    </div>
6  );
7}
8
9Countdown.defaultProps = {
10  seconds: 10,
11  color: 'red'
12};

W nowszych wersjach React można też używać domyślnych wartości bezpośrednio w destrukturyzacji:

1function Countdown({ seconds = 10, color = 'red' }) {
2  return (
3    <div style={{ color }}>
4      T-minus: {seconds} sekund
5    </div>
6  );
7}

Przekazywanie funkcji jako props

Jednym z najważniejszych zastosowań props jest przekazywanie funkcji, które pozwalają dziecku komunikować się z rodzicem:

1function MissionControl() {
2  const handleLaunch = () => {
3    alert('Odpalenie rakiety!');
4  };
5  
6  return (
7    <div className="mission-control">
8      <h2>Centrum Kontroli Misji</h2>
9      <LaunchPad onLaunch={handleLaunch} />
10    </div>
11  );
12}
13
14function LaunchPad({ onLaunch }) {
15  return (
16    <div className="launch-pad">
17      <h3>Platforma startowa</h3>
18      <button onClick={onLaunch}>
19        Rozpocznij odliczanie i wystrzel
20      </button>
21    </div>
22  );
23}

W tym przykładzie komponent potomny

LaunchPad
może wywołać funkcję przekazaną przez rodzica, co pozwala na komunikację "w górę".

Spread operatory dla props

Jeśli masz obiekt zawierający wiele właściwości, które chcesz przekazać jako props, możesz użyć operatora spread:

1function App() {
2  const rocketProps = {
3    name: 'Falcon Heavy',
4    manufacturer: 'SpaceX',
5    height: '70 m',
6    thrust: '22,819 kN'
7  };
8  
9  return (
10    <div className="app">
11      <h1>Informacje o rakiecie</h1>
12      <Rocket {...rocketProps} />
13    </div>
14  );
15}
16
17function Rocket({ name, manufacturer, height, thrust }) {
18  return (
19    <div className="rocket">
20      <h2>{name}</h2>
21      <ul>
22        <li>Producent: {manufacturer}</li>
23        <li>Wysokość: {height}</li>
24        <li>Ciąg: {thrust}</li>
25      </ul>
26    </div>
27  );
28}

Props.children

Specjalny prop

children
zawiera wszystko, co jest umieszczone między tagami otwierającym i zamykającym komponentu:

1function Card({ title, children }) {
2  return (
3    <div className="card">
4      <div className="card-header">
5        <h3>{title}</h3>
6      </div>
7      <div className="card-body">
8        {children}
9      </div>
10    </div>
11  );
12}
13
14// Użycie
15function App() {
16  return (
17    <Card title="Status misji">
18      <p>Wszystkie systemy działają prawidłowo.</p>
19      <button>Więcej szczegółów</button>
20    </Card>
21  );
22}

Immutability props

Bardzo ważne jest zrozumienie, że props są tylko do odczytu. Komponent nie powinien nigdy modyfikować swoich własnych props. Takie zachowanie narusza zasadę "jednokierunkowego przepływu danych" w React.

1// ŹLE - nigdy nie modyfikuj props!
2function BadComponent(props) {
3  props.value = 42; // Błąd!
4  return <div>{props.value}</div>;
5}
6
7// DOBRZE - używaj props tylko do odczytu
8function GoodComponent(props) {
9  return <div>{props.value}</div>;
10}

Jeśli potrzebujesz zmiennego stanu na podstawie props, możesz użyć

useState
z początkową wartością opartą na props:

1function Counter({ initialCount }) {
2  const [count, setCount] = useState(initialCount);
3  
4  return (
5    <div>
6      <p>Licznik: {count}</p>
7      <button onClick={() => setCount(count + 1)}>
8        Zwiększ
9      </button>
10    </div>
11  );
12}

Podsumowanie

Props są podstawowym mechanizmem komunikacji między komponentami w React. Pozwalają na:

  1. Przekazywanie danych z rodzica do dziecka
  2. Przekazywanie funkcji umożliwiających komunikację z dziecka do rodzica
  3. Dostosowywanie wyglądu i zachowania komponentów
  4. Tworzenie elastycznych, wielokrotnego użytku komponentów

Dobrą praktyką jest:

  • Ograniczanie liczby props do niezbędnego minimum
  • Używanie PropTypes do walidacji typów
  • Traktowanie props jako niezmiennych (read-only)
  • Używanie destrukturyzacji dla większej czytelności

W kolejnych sekcjach nauczymy się, jak uzupełnić props o stan (state), aby tworzyć w pełni interaktywne komponenty.

Przejdź do CodeWorlds