React: решение ошибки "TypeError: Cannot read property 'map' of undefined"

Ошибка "TypeError: Cannot read property 'map' of undefined" в React возникает, когда компонент пытается вызвать метод map
на значении, которое является undefined
. Такая ошибка часто встречается при работе с массивами данных, особенно если данные получены асинхронно. Разберём причины и пути решения этой ошибки.
Почему возникает ошибка "Cannot read property 'map' of undefined"
Ошибка появляется, когда переменная, на которой вызывается метод map
, не является массивом. Основные причины:
- Асинхронные данные: При загрузке данных асинхронно, переменная может быть
undefined
до завершения загрузки. - Отсутствие проверки данных: Если данные не проверяются перед их использованием, то метод
map
будет вызван наundefined
илиnull
. - Ошибки при инициализации состояния: Неправильная инициализация состояния компонента также может привести к тому, что данные будут
undefined
на момент их использования.
Пример возникновения ошибки
Рассмотрим простой пример, где ошибка происходит из-за асинхронной загрузки данных:
import React, { useState, useEffect } from 'react';
function ItemList() {
const [items, setItems] = useState();
useEffect(() => {
fetch('/api/items')
.then(response => response.json())
.then(data => setItems(data));
}, []);
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
В этом примере, поскольку items
не инициализированы как массив, вызов items.map
вызывает ошибку. Исправим это, добавив проверку данных перед вызовом map
:
import React, { useState, useEffect } from 'react';
function ItemList() {
const [items, setItems] = useState([]);
useEffect(() => {
fetch('/api/items')
.then(response => response.json())
.then(data => setItems(data));
}, []);
return (
<ul>
{items.length > 0 ? (
items.map(item => <li key={item.id}>{item.name}</li>)
) : (
<li>Загрузка данных...</li>
)}
</ul>
);
}
Теперь данные будут проверяться, и пока items
не загрузились, отобразится сообщение о загрузке.
Использование Optional Chaining для упрощения проверок
Для упрощения проверок можно использовать оператор Optional Chaining ( ?.
), чтобы избежать ошибок, если переменная undefined
:
return (
<ul>
{items?.map(item => (
<li key={item.id}>{item.name}</li>
)) || <li>Загрузка данных...</li>}
</ul>
);
Использование items?.map
предотвращает вызов метода, если items
равен undefined
или null
.
Инициализация состояния по умолчанию
Чтобы избежать подобных ошибок, полезно инициализировать состояние с пустым массивом. Это гарантирует, что map
будет вызываться на массиве даже до загрузки данных.
Для глубокого понимания работы с массивами и состояниями в React, изучите также статью о правильной работе с хуками.