04. React - Components a Props

12.02.2019 Programování #react #learning

Komponenty umožňují rozdělit JS kód nezávislé uživatelské rozhraní na opakovaně použitelné fragmenty a tím můžeme o každém fragmentu přemýšlet izolovaně.


Koncepčně jsou komponenty jako funkce JavaScriptu. Přijímají libovolné vstupy (nazývané "props") a vrací prvky React, které popisují, co se má zobrazit na obrazovce.

Funkce a třídy komponent

Nejjednodušší způsob, jak definovat komponentu, je napsat funkci JavaScript:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

Tato funkce je platná komponenta React, protože přijímá jediný argument "props" (což znamená vlastnosti) s daty a vrátí prvek React. Tyto komponenty nazýváme "funkcemi", protože jsou doslova funkcemi JavaScriptu.

K definici součásti můžete také použít třídu ES6:

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

Výše uvedené dva příklady jsou z pohledu Reactu ekvivalentní.

Vykreslení komponent

Dříve jsme se setkali pouze s prvky React, které představují značky DOM:

const element = <div />;

Prvky však mohou také představovat komponenty definované uživatelem:

const element = <Welcome name="Sara" />;

Když React vidí prvek představující součást definovanou uživatelem, předává atributy JSX této komponentě jako jediný objekt. Tento objekt nazýváme "props".

Například tento kód zobrazuje na stránce "Dobrý den, Sara":

GitHub

Zjistěte, co se v tomto příkladu děje:

  1. Voláme ReactDOM.render() s prvkem < welcome name="Sara" / >.
  2. React volá komponentu Welcome s {name: 'Sara'} jako props.
  3. Náš prvek Welcome vrací výsledný prvek < h1 >Hello, Sara< /h1 >.
  4. React DOM efektivně aktualizuje tak, aby výsledný DOM odpovídal < h1 >Hello, Sara< /h1 >.

Poznámka: Názvy komponent vždy nazývejte velkým písmenem. React zpracovává značky začínající malými písmeny jako značky DOM. Například < div / > představuje tag HTML div, ale < Welcome /> představuje komponentu a vyžaduje, Welcome.

Kompozice komponent

Komponenty mohou odkazovat na jiné komponenty svého výstupu. To umožňuje používat stejnou abstrakci komponent pro libovolnou úroveň podrobností. Tlačítko, formulář, dialog, obrazovka: v aplikacích Reactu, jsou všechny obvykle vyjádřeny jako komponenty.

Například můžeme vytvořit komponentu App, která vícekrát vykresluje Welcome:

GitHub

Typicky nová React aplikace má jedinou komponentu App na vrcholu. Pokud však React začleníte do existující aplikace, můžete spustit zdola nahoru s malou komponentou Button a budete postupovat na vrchol v hierarchii zobrazení.

Extrakce komponent

Nebojte se rozdělit komponent na menší.

Podívejte se například na komponentu Comment:

GitHub

Uvedená komponenta popisuje komentář na webu např. na sociálních sítích. Přijímá author (objekt), text (řetězec) a date (datum) jako props.

Tato komponenta může být obtížně měnitelná kvůli komplexnímu výpisu a nelze použít znovu jednotlivé části. Vyjmeme z ní pár komponent.

Nejdříve vytvoříme Avatar:

function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />

  );
}

Avatar nepotřebuje vědět, že je právě vykreslen uvnitř Comment.

Můžeme nyní Comment trochu zjednodušit:

function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <Avatar user={props.author} />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

Dále vytvoříme část UserInfo, která vykreslí Avatar vedle jména uživatele:

function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  );
}

To umožňuje komponentu Comment ještě zjednodušit:

function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

Extrahování komponent se může jevit jako zbytečná práce, ale je výhodné mít paletu znovupoužitelných komponent. Pokud je v uživatelským rozhraní několik prvků jako je Button, Panel nebo Avatar, nebo se jedná o složitou aplikaci, potom je vhodným kandidátem na vytvoření dílčích komponent.

Props jsou pouze pro čtení

Ať už deklarujte komponentu jako součást funkce nebo třídy, nesmí nikdy měnit vlastní props. Podívejte se na funkci:

function sum(a, b) {
  return a + b;
}

Tyto funkce se nazývají "čisté", protože se nepokoušejí měnit své vstupy a vždy vrátí stejný výsledek pro stejné vstupy.

Naopak funkce je nečistá, pokud mění svůj vlastní vstup:

function withdraw(account, amount) {
  account.total -= amount;
}

React je docela flexibilní, ale má jedno přísné pravidlo:
Všechny komponenty React se musí chovat jako čisté funkce, pokud jde o jejich props.