Списки и ключи¶
Сначала давайте вспомним, как работать со списками в JavaScript.
В коде ниже мы используем функцию map()
, чтобы удвоить значения в массиве numbers
. Мы присваиваем массив, возвращаемый из map()
, переменной doubled
, и выводим её в консоль:
1 2 3 |
|
Этот код выведет [2, 4, 6, 8, 10]
в консоль.
В React преобразование массивов в список элементов выглядит похожим образом.
Рендер нескольких компонентов¶
Вы можете создать коллекцию элементов и встроить её в JSX с помощью фигурных скобок {}
.
К примеру, пройдём по массиву numbers
, используя функцию JavaScript map()
, и вернём элемент <li>
в каждой итерации. Получившийся массив элементов сохраним в listItems
:
1 2 |
|
Теперь мы включим массив listItems
внутрь элемента <ul>
и отрендерим его в DOM:
1 2 3 4 |
|
Этот код выведет список чисел от 1 до 5.
Простой компонент-список¶
Как правило, вы будете рендерить списки внутри какого-нибудь компонента.
Мы можем отрефакторить предыдущий пример с использованием компонента, который принимает массив numbers
и выводит список элементов.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Когда вы запустите данный код, то увидите предупреждение о том, что у каждого элемента массива должен быть ключ (key). «Ключ» – это специальный строковый атрибут, который нужно указывать при создании списка элементов. Мы обсудим, почему это важно, ниже на странице.
Чтобы исправить проблему с неуказанными ключами, добавим каждому элементу в списке атрибут key
.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Ключи¶
Ключи помогают React определять, какие элементы были изменены, добавлены или удалены. Их необходимо указывать, чтобы React мог сопоставлять элементы массива с течением времени:
1 2 3 4 |
|
Лучший способ выбрать ключ – это использовать строку, которая будет явно отличать элемент списка от его соседей. Чаще всего вы будете использовать ID из ваших данных как ключи:
1 2 3 |
|
Когда у вас нет заданных ID для списка, то в крайнем случае можно использовать индекс элемента как ключ:
1 2 3 4 |
|
Мы не рекомендуем использовать индексы как ключи, если порядок элементов может поменяться. Это негативно скажется на производительности и может вызвать проблемы с состоянием компонента. Почитайте статью Робина Покорни (Robin Pokorny), которая объясняет, почему индексы-ключи приводят к проблемам. Если вы опустите ключ для элемента в списке, то React по умолчанию будет использовать индексы как ключи.
Вот подробное объяснение о том, почему ключи необходимы.
Извлечение компонентов с ключами¶
Ключи нужно определять непосредственно внутри массивов.
Например, если вы извлекаете компонент ListItem
, то нужно указывать ключ для <ListItem />
в массиве, а не в элементе <li>
внутри самого ListItem
.
Пример неправильного использования ключей
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Пример правильного использования ключей
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Как правило, элементам внутри map()
нужны ключи.
Ключи должны быть уникальными среди соседних элементов¶
Ключи внутри массива должны быть уникальными только среди своих соседних элементов. Им не нужно быть уникальными глобально. Можно использовать один и тот же ключ в двух разных массивах.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
Ключи служат подсказками для React, но они никогда не передаются в ваши компоненты. Если в компоненте нужно то же самое значение, то передайте его явно через проп с другим именем:
1 2 3 |
|
В примере выше компонент Post
может прочитать значение props.id
, но не props.key
.
Встраивание map() в JSX¶
В примерах выше мы отдельно определяли переменную listItems
и вставляли её в JSX:
1 2 3 4 5 6 7 |
|
JSX позволяет встроить любое выражение в фигурные скобки, так что мы можем включить результат выполнения map()
:
1 2 3 4 5 6 7 8 9 10 |
|
Иногда это приводит к более чистому коду, но бывает и наоборот. Как и в любом JavaScript-коде, вам придётся самостоятельно решать, стоит ли извлекать код в переменную ради читабельности. Не забывайте, что если код внутри map()
слишком громоздкий, имеет смысл извлечь его в отдельный компонент.