Швидкий старт

Ласкаво просимо до документації React! Ця сторінка дасть вам уявлення про 80% концепцій React, які ви будете використовувати щодня.

You will learn

  • Як створювати та вкладати компоненти
  • Як додати розмітку та стилі
  • Як відображати дані
  • Як відображати умови та списки
  • Як реагувати на події та оновлювати екран
  • Як обмінюватися даними між компонентами

Створення та вкладеність компонентів

React додатки складаються з компонентів. Компонент це частина UI (інтерфейсу користувача), яка має власну логіку та зовнішній вигляд. Компонент може бути маленьким, як кнопка, або ж розміром з цілу сторінку.

React компоненти це JavaScript функції які повертають розмітку:

function MyButton() {
return (
<button>Я кнопка</button>
);
}

Тепер, коли ви оголосили MyButton, ви можете вставити його в інший компонент:

export default function MyApp() {
return (
<div>
<h1>Ласкаво просимо до мого додатку</h1>
<MyButton />
</div>
);
}

Зверніть увагу, що <MyButton /> починається з великою літери. Таким чином ви розумієте, що це React-компонент. Назви компонентів React завжди мають починатися з великої літери, тоді як теги HTML мають бути у нижньому регістрі.

Погляньте на результат:

function MyButton() {
  return (
    <button>
      Я кнопка
    </button>
  );
}

export default function MyApp() {
  return (
    <div>
      <h1>Ласкаво просимо до мого додатку</h1>
      <MyButton />
    </div>
  );
}

Ключові слова export default вказують на головний компонент у файлі. Якщо ви не знайомі з деякими частинами JavaScript синтаксису, MDN та javascript.info мають чудові матеріали.

Написання розмітки з використанням JSX

Синтаксис розмітки, яку ви бачили вище має назву JSX. Це необов’язково, але більшість React-проектів використовують JSX для зручності. Усі інструменти, які ми рекомендуємо для локальної розробки підтримують JSX з коробки.

JSX більш строгий, ніж HTML. Ви зобов’язані закривати такі теги як <br />. Також ваш компонент не може повертати декілька JSX тегів. Ви повинні огортати їх у спільний батьківський елемент, такий як <div>...</div> або пусту <>...</> обгортку:

function AboutPage() {
return (
<>
<h1>Про нас</h1>
<p>Привіт<br />Як ваші справи?</p>
</>
);
}

Якщо у вас є багато HTML для портування у JSX, ви можете використовувати онлайн конвертер.

Додавання стилів

У React, ви вказуєте клас CSS за допомогою className. Він працює так само, як атрибут class у HTML:

<img className="avatar" />

Потім ви записуєте для нього правила CSS в окремому файлі CSS:

/* У вашому CSS */
.avatar {
border-radius: 50%;
}

React does not prescribe how you add CSS files. In the simplest case, you’ll add a <link> tag to your HTML. If you use a build tool or a framework, consult its documentation to learn how to add a CSS file to your project.

React не вказує, як додавати файли CSS. У найпростішому випадку ви додасте тег <link> до свого HTML. Якщо ви використовуєте інструмент збірки або фреймворк, зверніться до його документації, щоб дізнатися, як додати файл CSS до вашого проекту.

Відображення даних

JSX дозволяє розміщувати розмітку в JavaScript. Фігурні дужки дозволяють вам «втекти назад» до JavaScript, щоб ви могли вставити якусь змінну зі свого коду та показати її користувачеві. Наприклад, це відобразить user.name:

return (
<h1>
{user.name}
</h1>
);

Також ви можете “повернутись до JavaScript” з атрибутів JSX, але вам доведеться використати фігурні дужки замість лапок. Наприклад, className="avatar" передає рядок "avatar" як клас CSS, але src={user.imageUrl} читає значення JavaScript змінної user.imageUrl, і тоді передає це значення як атрибут src:

return (
<img
className="avatar"
src={user.imageUrl}
/>
);

Ви також можете розміщувати складніші вирази у фігурних дужках JSX, наприклад, конкатенація рядків:

const user = {
  name: 'Геді Ламар',
  imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
  imageSize: 90,
};

export default function Profile() {
  return (
    <>
      <h1>{user.name}</h1>
      <img
        className="avatar"
        src={user.imageUrl}
        alt={'Фото ' + user.name}
        style={{
          width: user.imageSize,
          height: user.imageSize
        }}
      />
    </>
  );
}

У наведеному вище прикладі style={{}} — це не спеціальний синтаксис, а звичайний об’єкт {} у фігурних дужках JSX style={ }. Ви можете використовувати атрибут style, якщо ваші стилі залежать від змінних JavaScript.

Умовний рендер

In React, there is no special syntax for writing conditions. Instead, you’ll use the same techniques as you use when writing regular JavaScript code. For example, you can use an if statement to conditionally include JSX:

У React немає спеціального синтаксису для запису умов. Замість цього ви будете використовувати ті ж прийоми, що й під час написання звичайного JavaScript коду. Наприклад, ви можете використовувати оператор if, щоб умовно включати JSX:

let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);

Якщо ви віддаєте перевагу більш компактному коду, ви можете використовувати умовний оператор ?. На відміну від if, він працює в JSX:

<div>
{isLoggedIn ? (
<AdminPanel />
) : (
<LoginForm />
)}
</div>

Якщо вам не потрібна гілка else, ви також можете використовувати коротший логічний синтаксис &&:

<div>
{isLoggedIn && <AdminPanel />}
</div>

Усі ці підходи також працюють для умовного визначення атрибутів. Якщо ви не знайомі з частиною цього синтаксису JavaScript, ви можете почати, завжди використовуючи if...else.

Рендер списків

Для рендеру списків компонентів ви будете покладатися на такі особливості JavaScript, як цикл for та метод масивів map().

Наприклад, припустімо, що у вас є масив продуктів:

const products = [
{ title: 'Капуста', id: 1 },
{ title: 'Часник', id: 2 },
{ title: 'Яблуко', id: 3 },
];

У вашому компоненті використовуйте функцію map() для перетворення масиву продуктів на масив елементів <li>:

const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);

return (
<ul>{listItems}</ul>
);

Зверніть увагу, що <li> має атрибут key. Для кожного елемента в списку ви повинні передати рядок або число, яке однозначно ідентифікує цей елемент серед елементів одного рівня. Зазвичай ключ має надходити з ваших даних, наприклад ідентифікатор бази даних. React використовує ваші ключі, щоб знати, що сталося, якщо ви пізніше вставите, видалите або зміните порядок елементів.

const products = [
  { title: 'Капуста', isFruit: false, id: 1 },
  { title: 'Часник', isFruit: false, id: 2 },
  { title: 'Яблуко', isFruit: true, id: 3 },
];

export default function ShoppingList() {
  const listItems = products.map(product =>
    <li
      key={product.id}
      style={{
        color: product.isFruit ? 'пурпуровий' : 'темно-зелений'
      }}
    >
      {product.title}
    </li>
  );

  return (
    <ul>{listItems}</ul>
  );
}

Реагування на події

Ви можете реагувати на події, оголошуючи функції обробника подій у своїх компонентах:

function MyButton() {
function handleClick() {
alert('Ви натиснули на мене!');
}

return (
<button onClick={handleClick}>
Натисни на мене
</button>
);
}

Зверніть увагу, що onClick={handleClick} не має дужок у кінці! Не викликайте функцію обробника подій: вам потрібно лише передати її. React викличе ваш обробник подій, коли користувач натисне кнопку.

Оновлення екрану

Часто вам потрібно, щоб ваш компонент “запам’ятав” деяку інформацію та відобразив її. Наприклад, можливо, ви хочете підрахувати кількість натискань кнопки. Для цього додайте стан до свого компонента.

Спочатку, імпортуйте useState з React:

import { useState } from 'react';

Тепер ви можете оголосити змінну стану всередині вашого компонента:

function MyButton() {
const [count, setCount] = useState(0);
// ...

Ви отримаєте дві речі від useState: поточний стан (count) і функцію, яка дозволяє його оновити (setCount). Ви можете дати їм будь-які назви, але прийнято писати [something, setSomething].

Під час першого відображення кнопки count буде 0, тому що ви передали 0 в useState(). Якщо ви хочете змінити стан, викличте setCount() і передайте йому нове значення. Натискання цієї кнопки збільшить лічильник:

function MyButton() {
const [count, setCount] = useState(0);

function handleClick() {
setCount(count + 1);
}

return (
<button onClick={handleClick}>
Натиснуто {count} разів
</button>
);
}

React знову викличе вашу функцію компонента. Цього разу «count» буде «1». Тоді це буде “2”. І так далі.

Якщо ви візуалізуєте той самий компонент кілька разів, кожен матиме свій власний стан. Натисніть кожну кнопку окремо:

import { useState } from 'react';

export default function MyApp() {
  return (
    <div>
      <h1>Лічильники, які оновлюються окремо</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Натиснуто {count} разів
    </button>
  );
}

Зверніть увагу, як кожна кнопка “пам’ятає” свій власний стан count і не впливає на інші кнопки.

Використання хуків

Функції, що починаються з use, називаються хуками. useState — це вбудований хук, наданий React. Ви можете знайти інші вбудовані хуки в API довіднику. Також ви можете написати власні хуки, комбінуючи існуючі.

Хуки є більш обмежувальними, ніж інші функції. Ви можете викликати хуки лише вгорі ваших компонентів (або інших хуків). Якщо ви хочете використовувати useState в умові або циклі, витягніть новий компонент і помістіть його туди.

Обмін даними між компонентами

У попередньому прикладі кожен MyButton мав власний незалежний count, і коли натискали кожну кнопку, змінювався лише count для натиснутої кнопки:

Діаграма, на якій показано дерево з трьох компонентів, один із батьківських компонентів із позначкою MyApp і два дочірні з позначкою MyButton. Обидва компоненти MyButton містять лічильник із нульовим значенням.
Діаграма, на якій показано дерево з трьох компонентів, один із батьківських компонентів із позначкою MyApp і два дочірні з позначкою MyButton. Обидва компоненти MyButton містять лічильник із нульовим значенням.

Спочатку, для кожно MyButton стан count має значення 0

Та сама діаграма, що й у попередній, із підрахунком першого дочірнього компонента MyButton, виділеним, що вказує на клацання зі значенням підрахунку, збільшеним до одиниці. Другий компонент MyButton все ще містить нульове значення.
Та сама діаграма, що й у попередній, із підрахунком першого дочірнього компонента MyButton, виділеним, що вказує на клацання зі значенням підрахунку, збільшеним до одиниці. Другий компонент MyButton все ще містить нульове значення.

Перший MyButton оновлює count до 1

Однак часто вам знадобляться компоненти для спільного використання даних і завжди спільного оновлення.

Щоб змусити обидва компоненти MyButton відображати однаковий count і оновлювати разом, вам потрібно перемістити стан від окремих кнопок “вгору” до найближчого компонента, який їх усі містить.

У цьому прикладі це MyApp:

Діаграма, на якій показано дерево з трьох компонентів, один із батьківських компонентів із позначкою MyApp і два дочірні з позначкою MyButton. MyApp містить нульове значення підрахунку, яке передається до обох компонентів MyButton, які також показують нульове значення.
Діаграма, на якій показано дерево з трьох компонентів, один із батьківських компонентів із позначкою MyApp і два дочірні з позначкою MyButton. MyApp містить нульове значення підрахунку, яке передається до обох компонентів MyButton, які також показують нульове значення.

Спочатку, стан count у MyApp дорівнює 0 і передається обом дочірнім елементам

Та сама діаграма, що й у попередній, із підрахунком батьківського компонента MyApp, виділеним, що вказує на клацання зі значенням, збільшеним до одиниці. Потік до обох дочірніх компонентів MyButton також виділено, а значення підрахунку в кожному дочірньому компоненті встановлено на одиницю, що вказує на те, що значення було передано.
Та сама діаграма, що й у попередній, із підрахунком батьківського компонента MyApp, виділеним, що вказує на клацання зі значенням, збільшеним до одиниці. Потік до обох дочірніх компонентів MyButton також виділено, а значення підрахунку в кожному дочірньому компоненті встановлено на одиницю, що вказує на те, що значення було передано.

Після натискання MyApp оновлює свій стан count до 1 і передає його обом нащадкам

Тепер, коли ви натискаєте будь-яку кнопку, count у MyApp зміниться, що змінить обидва лічильники в MyButton. Ось як ви можете виразити це в коді.

Спочатку підніміть стан з MyButton до MyApp:

export default function MyApp() {
const [count, setCount] = useState(0);

function handleClick() {
setCount(count + 1);
}

return (
<div>
<h1>Лічильники, які оновлюються окремо</h1>
<MyButton />
<MyButton />
</div>
);
}

function MyButton() {
// ... ми переносимо код звідси ...
}

Потім передайте стан від MyApp до кожного MyButton разом зі спільним обробником кліків. Ви можете передавати інформацію в MyButton за допомогою фігурних дужок JSX, так само, як ви робили раніше з вбудованими тегами, як-от <img>:

export default function MyApp() {
const [count, setCount] = useState(0);

function handleClick() {
setCount(count + 1);
}

return (
<div>
<h1>Лічильники, які оновлюються окремо</h1>
<MyButton count={count} onClick={handleClick} />
<MyButton count={count} onClick={handleClick} />
</div>
);
}

Інформація, яку ви передаєте таким чином, називається пропси. Тепер компонент MyApp містить стан count і обробник події handleClick і передає їх обидва як пропси для кожної з кнопок.

Нарешті, змініть MyButton на читання пропсів, які ви передали від його батьківського компонента:

function MyButton({ count, onClick }) {
return (
<button onClick={onClick}>
Натиснуто {count} разів
</button>
);
}

Коли ви натискаєте кнопку, запускається обробник onClick. Проп onClick кожної кнопки було налаштовано на функцію handleClick всередині MyApp, тому код у ньому виконується. Цей код викликає setCount(count + 1), збільшуючи змінну стану count. Нове значення count передається як атрибут для кожної кнопки, тому всі вони показують нове значення. Це називається «підйом стану». Піднявши стан вгору, ви поділилися ним між компонентами.

import { useState } from 'react';

export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Лічильники, які оновлюються окремо</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

function MyButton({ count, onClick }) {
  return (
    <button onClick={onClick}>
      Натиснуто {count} разів
    </button>
  );
}

Подальші кроки

Тепер ви знаєте основи написання React коду!

Перегляньте Навчальний посібник щоб застосувати їх на практиці та створити свій перший міні-додаток із React.