SkillGridИзучай computer science на практике

Компоненты: функция, которая возвращает экран

Компонент как функция с входами и одним выходом, props как входы только для чтения и почему собирать большое из маленького лучше, чем копировать и вставлять.

14 мин · 45 XP

Откройте любое настоящее приложение и посчитайте мелкие повторяющиеся кусочки: бейдж, цена, строка списка, карточка товара. Каждый из них — компонент. Написать его — не столько новый навык, сколько старый навык в другой одежде.

В разделе про языки функция была именованной коробкой: значения входят, одно значение выходит, а имя — это то, как её вызывают. Компонент — ровно такая коробка с одной разницей: на выходе получается кусок интерфейса.

function totalPrice(price, count) {
  return price * count;
}

totalPrice(2.50, 4);

function Badge({ label }) {
  return <span className="badge">{label}</span>;
}

const view = <Badge label="New" />;Одна и та же форма дважды: числа на входе и число на выходе, props на входе и элементы на выходе.

В этом весь фокус. Компонент — это именованный кусок интерфейса. Вы даёте ему имя, говорите, что ему нужно, и дальше остальная программа может попросить бейдж или строку с ценой, не зная, как нарисовано то или другое.

Вот каталог: три товара, одна форма карточки. Написана один раз, использована трижды.

function ProductCard({ title, price, inStock }) {
  return (
    <article>
      <h2>{title}</h2>
      <p>{price}</p>
      {inStock ? <button>Add</button> : <p>Sold out</p>}
    </article>
  );
}

function Catalogue() {
  return (
    <section>
      <ProductCard title="Bread" price="2.50" inStock={true} />
      <ProductCard title="Tea" price="3.20" inStock={false} />
      <ProductCard title="Apples" price="1.80" inStock={true} />
    </section>
  );
}Одна карточка, описанная один раз, использованная трижды с разными входами.

Входы записываются как атрибуты и приходят вместе, одним объектом, который называется props. В этом примере карточка получает title, price и inStock и не интересуется, откуда они взялись.

function Price({ amount }) {
  amount = amount + 1;
  return <p>{amount}</p>;
}

function Price({ amount }) {
  const [shown, setShown] = useState(amount);
  return <p>{shown}</p>;
}Вторая версия лучше не потому, что длиннее. Она лучше потому, что число теперь принадлежит компоненту, который его меняет.
CatalogueProductCardElementstitle = Tea, price = 3.20runs like any functionh2, p, buttonP never reaches inside C

Честная альтернатива компонентам — копирование и вставка, и для двух карточек это нормально. Счёт приходит позже. Дизайнер просит скруглить углы у каждой карточки: теперь вы правите двенадцать файлов. Правило расчёта цены меняется, теперь в неё входит налог: вы исправляете девять файлов, три пропускаете, и каталог показывает две разные цены на один и тот же товар. Компонент превращает каждое такое изменение в одну правку в одном месте, потому что есть только одно место, которое знает, как выглядит карточка.

Практика

  1. Компонент карточки товара получает title, price и inStock от каталога вокруг него. Ему нужно показать, распродан товар или нет. Что из этого компонент может перезаписать?

    Подсказки
    • Одно из этого — данные, пришедшие извне компонента. Всё, что компонент получает, попадает в эту категорию.
    • Prop не хранится внутри компонента. Если что-то внутри меняется само, оно не могло прийти как prop.
  2. Каталог рисует карточку товара для каждого полученного элемента. Расставьте путь от данных к пикселям по порядку.

    1. 1Карточка возвращает описание нужных ей элементов
    2. 2Элементы рисуются внутри страницы
    3. 3Функция карточки выполняется и читает эти входы
    4. 4Родитель создаёт карточку и передаёт ей входы
    Подсказки
    • Начните на шаг выше самой карточки и закончите тем, что браузер может нарисовать.
    • Внутри карточки путь идёт от собранных входов к возвращённым деревьям.
  3. Сопоставьте каждую часть компонента с той частью функции, которую она играет.

    Подсказки
    • Сопоставьте каждый кусок интерфейса с той ролью, которую он играет в функции.
    • Входы — это скобки, имя — то, как компонент вызывают снаружи, правило — то, что происходит внутри.