Ось готовий урок, написаний у стилі CS50, спеціально для теми "Рендеринг списків і key".
🎓 CS50: Рендеринг списків і таємниця атрибута key
Привіт, друзі! Радий вас бачити. Сьогодні ми зануримося в тему, яка перетворює статичні веб-сторінки на живі, динамічні додатки.
1. 🔥 Вступ: проблема та мотивація
Уявіть, що ви розробляєте наступний Instagram. Вам потрібно відобразити стрічку новин.
У вас є масив даних із сервера — скажімо, 100 постів. Як ви будете їх показувати?
Чи будете ви вручну писати в коді:
<Post />, потім ще один <Post />, і ще один... і так сто разів?
А що, якщо завтра постів стане 101? Або 50? Або нуль? Ви ж не будете переписувати код програми щоразу, коли хтось завантажує нове фото, правда? Це було б божевіллям.
Тут виникає фундаментальна проблема: Як нам змусити комп'ютер взяти купу "сухих" даних (масив) і автоматично перетворити їх на красиві інтерфейсні елементи (UI), незалежно від того, скільки їх там — один чи мільйон?
І найголовніше — як зробити це так, щоб ваш браузер не "завис", намагаючись оновити цей список?
Ось тут на сцену виходить рендеринг списків і той самий загадковий атрибут key, на який React постійно свариться в консолі червоним текстом. Давайте розберемося, навіщо це потрібно.
2. 🧠 Теоретична база (без сухої академічності)
Метод .map() — ваш конвеєр
У JavaScript (і в React) ми не використовуємо цикли for для рендерингу так часто, як в інших мовах. Ми використовуємо функціональне програмування.
Уявіть собі заводський конвеєр.
На вході у вас ящик сирої картоплі (ваш масив даних).
На конвеєрі стоїть робот (метод .map()).
Він бере кожну картоплину, чистить її, смажить і на виході видає пачку чіпсів (ваш HTML-елемент).
Головне правило: Метод
.map()бере масив даних і повертає новий масив, але вже з JSX-елементами.
Таємниця key (Ключ)
Коли ви створюєте список, React (або інша бібліотека) вимагає дати кожному елементу унікальний key. Чому?
Уявіть, що ви — вчитель у класі з 30 учнями. Ви кажете: "Всі пересядьте на одне місце вправо!". Якщо ви знаєте учнів лише за їхнім місцем ("Ей, ти за третьою партою!"), у вас буде хаос. Ви не знаєте, хто куди пересів. Але якщо у кожного учня є унікальне ім'я (ID), то навіть якщо вони поміняються місцями, ви точно знатимете: "Ага, Іван тепер тут, а Марія там".
Як це працює "під капотом"?
React використовує механізм Reconciliation (звірки). Він порівнює стару версію списку і нову.
* Без key: React думає, що ви видалили старий список і створили новий. Він "зносе" весь DOM і побудує заново. Це повільно.
* З key: React бачить: "О, елемент з ID=45 нікуди не зник, він просто переїхав нижче. Я просто пересуну його, не перемальовуючи вміст".
Запам'ятайте:
key— це паспорт елемента. Він має бути унікальним серед сусідів і стабільним (не змінюватися при кожному рендері).
3. 🧪 Приклади (від простого до реального)
Приклад 1: Простий список рядків
У нас є список покупок.
const products = ['Хліб', 'Молоко', 'Яблука'];
function ShoppingList() {
// Ми перетворюємо рядки на <li>
const listItems = products.map((product) => (
<li key={product}>
{product}
</li>
));
return <ul>{listItems}</ul>;
}
Питання до вас: Чому я використав назву продукту як key?
Відповідь: У цьому простому списку назви унікальні. Але якщо ми купимо два види "Хліба", React насварить за дублікат ключа.
Приклад 2: Реальний світ (Масив об'єктів)
У реальних проєктах дані приходять із бази даних і мають id. Це ідеальний кандидат для ключа.
const users = [
{ id: 101, name: "Олена", role: "Admin" },
{ id: 102, name: "Андрій", role: "User" },
{ id: 103, name: "Катя", role: "Editor" }
];
function UserList() {
return (
<div className="user-container">
{users.map((user) => (
// Зверніть увагу: key ставимо на найвищий елемент всередині map
<div key={user.id} className="user-card">
<h3>{user.name}</h3>
<p>Role: {user.role}</p>
</div>
))}
</div>
);
}
Що ви очікуєте побачити? Три картки користувачів.
Чому так? React взяв кожен об'єкт, підставив дані в шаблон HTML і використав id для відстеження. Якщо Олена видалить свій акаунт, React видалить із DOM тільки її div, не чіпаючи Андрія та Катю.
4. 🛠 Практична частина
Час кодити! Відкривайте редактор.
- 🔹 Повторення: Створіть масив
["React", "Angular", "Vue"]і виведіть його як маркований список (<ul>). - 🔹 Об'єкти: Створіть масив книг (об'єкти з полями
id,title,author). Виведіть їх у вигляді карток. - 🔹 Умови в списку: Використовуючи попередній масив книг, додайте поле
isRead: true/false. Відрендеріть список так, щоб прочитані книги мали зелений колір тексту, а непрочитані — червоний. - 🔹 Виправлення помилки:
javascript // Знайдіть проблему в цьому коді: const tasks = ["Спати", "Їсти", "Кодити", "Спати"]; tasks.map(task => <li key={task}>{task}</li>);Підказка: Що станеться з ключами, якщо задачі однакові? Як це виправити? (Додайте індекс другим аргументом map або зробіть дані унікальними). - 🔹 Міні-кейс: Уявіть, що ви робите меню для піцерії. Є масив піц. Виведіть тільки ті піци, які вегетаріанські (спочатку
filter, потімmap).
5. 💡 Мислення як у розробника
Ось де новачки часто помиляються, а профі — ні.
❌ Помилка №1: Використання index як ключа
Дуже спокусливо написати так:
users.map((user, index) => <li key={index}>{user.name}</li>)
Чому це погано? Уявіть чергу в магазин. 1. Андрій (index 0) 2. Оля (index 1)
Якщо Андрій піде, Оля стане першою (index 0). Для React це виглядає так, ніби Оля перетворилася на Андрія, бо ключ 0 залишився, просто змінив контент. Це ламає поля вводу, анімації та сортування.
Порада: Використовуйте index тільки якщо список ніколи не буде змінюватися, сортуватися чи фільтруватися. В іншому випадку — вимагайте у бекенда id.
❌ Помилка №2: Генерація ключів "на льоту"
key={Math.random()}
Ніколи так не робіть!
Це змушує React думати, що при кожному оновленні це зовсім нові елементи. Він буде видаляти старі та створювати нові постійно. Це вбиває продуктивність і втрачає фокус у полях вводу.
✅ Як думає профі:
"Які дані унікально ідентифікують цей елемент у базі даних? ID? URL? SKU товару? Оце і буде моїм ключем".
6. 🧩 Підсумок
Отже, що ми сьогодні розібрали?
- Ми не копіюємо код. Ми використовуємо масиви та метод
.map(), щоб генерувати інтерфейс динамічно. key— це не просто "щоб консоль не сварилась". Це критично важливий інструмент для продуктивності та коректності роботи React.- Ключі мають бути стабільними та унікальними серед братів-елементів.
Тепер ви вмієте: Створювати сторінки, які можуть відображати 5 товарів або 5000, використовуючи один і той самий шаблон коду. Ви зробили величезний крок до створення реальних додатків!
🔜 Що далі? Зараз наші списки просто "висять". А що, якщо ми хочемо додати кнопку "Видалити" біля кожного товару або форму для додавання нового? Наступного разу ми поговоримо про State (Стан) та обробку подій, щоб оживити ці списки!
А поки що — це був CS50. Щасти вам у коді!