Перейти к содержимому

6. Списки и ключи

Иллюстрация к уроку В React часто возникает необходимость отображать списки данных. В этом уроке мы разберем, как правильно это делать, и почему ключи (keys) играют такую важную роль.

Для отображения списков в React мы обычно используем метод map() для преобразования массива данных в массив React-элементов.

function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);

В этом примере мы передаем массив чисел в компонент NumberList, который использует map() для создания массива <li> элементов. Затем этот массив отображается внутри <ul>.

Хотя код выше работает, React выдаст предупреждение в консоли: “Each child in a list should have a unique “key” prop”. Ключи помогают React идентифицировать, какие элементы списка были изменены, добавлены или удалены. Это необходимо для эффективного обновления DOM.

Ключи должны быть уникальными среди соседних элементов. В идеале, ключ должен быть стабильным и предсказуемым, например, ID из базы данных.

function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);

В этом примере мы использовали строковое представление числа в качестве ключа. Это работает, так как числа уникальны в нашем списке.

Важно: Не используйте индекс массива в качестве ключа, если порядок элементов может измениться. Это может привести к проблемам с производительностью и неожиданным поведением компонента.

// Плохой пример: использование индекса в качестве ключа
const listItems = numbers.map((number, index) =>
<li key={index}>
{number}
</li>
);

Если у вас нет уникального ID, и порядок элементов не меняется, использование индекса допустимо, но предпочтительнее найти другой, более надежный способ.

В большинстве веб-приложений вы будете работать с данными, полученными из API или базы данных. Эти данные часто содержат уникальные идентификаторы. Например, список задач (todos):

const todos = [
{ id: 1, text: 'Купить продукты' },
{ id: 2, text: 'Сделать домашнее задание' },
{ id: 3, text: 'Позвонить врачу' },
];
function TodoList(props) {
const todos = props.todos;
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
);
return (
<ul>{todoItems}</ul>
);
}
ReactDOM.render(
<TodoList todos={todos} />,
document.getElementById('root')
);

В этом примере, todo.id используется как ключ, что является хорошей практикой. Такой подход используется в большинстве React-приложений, например, при отображении списка товаров в интернет-магазине, списка постов в блоге и т.д. Фреймворки типа Next.js и Gatsby.js активно используют ключи для оптимизации рендеринга списков.

  • При отображении списков в React необходимо использовать атрибут key.
  • Ключи должны быть уникальными среди соседних элементов.
  • Предпочтительно использовать стабильные и предсказуемые ключи (например, ID из базы данных).
  • Избегайте использования индекса массива в качестве ключа, если порядок элементов может измениться.
  • Правильное использование ключей повышает производительность и стабильность React-приложений.