#javascript #reactjs
Вопрос:
Я действительно застрял на проблеме — если вы запустите приведенный ниже код, вы получите сообщение об ошибке «Ошибка типа: Не удается прочитать свойства неопределенного (чтение «карты»)».
Когда я консольно выхожу из var «элементы», я получаю 2 результата, как показано здесь:
Проблема заключается в первом результате, поскольку он пуст. Но может ли кто-нибудь объяснить мне, почему этот результат пуст и почему он дает 2 результата?
Этот код был взят непосредственно отсюда и изменен в соответствии с тем, что возвращается из API. Пожалуйста, подумайте о том, чтобы запустить этот код, чтобы вы могли понять, что я имею в виду.
import React, {useState, useEffect} from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
const [error, setError] = useState(null);
const [isLoaded, setIsLoaded] = useState(false);
const [items, setItems] = useState([]);
useEffect(() => {
fetch("http://www.7timer.info/bin/api.pl?lon=113.17amp;lat=23.09amp;product=astroamp;output=json")
.then(res => res.json())
.then(
(result) => {
setIsLoaded(true);
setItems(result);
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
setIsLoaded(true);
setError(error);
}
)
}, [])
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<ul>
{items.dataseries.map(item => (
{console.log(item)}
))}
</ul>
);
}
}
export default App;
Комментарии:
1. У вашего
items
состояния var нет атрибутаdataseries
при первой загрузке. Вам нужно будет проверить это в функции рендеринга, прежде чем выполнять рендеринг сmap
помощью .
Ответ №1:
Есть две ошибки, которые я мог видеть
- Одним из них является то, что данные, которые вы извлекаете, являются объектом, в то время как вы изначально настраиваете его как массив, и вы также используете функцию карты, которая может использоваться только для массивов.
- Изначально ваш массив не содержит
dataseries
, и вы не можете получить доступ к такому свойству в правом массиве (потому что у массива есть индексы, по которым мы получаем значение).
Итак, что вы могли бы сделать, вместо этого установите эту функцию такой
useEffect(() => {
fetch("http://www.7timer.info/bin/api.pllon=113.17amp;lat=23.09amp;product=astroamp;output=json")
.then(res => res.json())
.then(
(result) => {
setIsLoaded(true);
setItems(result.dataseries);
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
setIsLoaded(true);
setError(error);
}
)}, [])
И функция возврата должна быть примерно такой
return (
<ul>
{items.map(item => (
{console.log(item)}
))}
</ul>
);
Комментарии:
1. Идеальный. Ты-ответ, решивший мою проблему. Но мне любопытно, знаете ли вы, почему значение выводится дважды? Кроме того, если я задаю состояние как объект и сохраняю результат, почему я не могу получить доступ к элементам.наборы данных в функции карты?
2. Да, потому что React не работает таким образом, что сначала он ожидает получения всех запросов, а затем отображает содержимое. Всякий раз, когда компонент монтируется, он визуализируется с помощью всего, что доступно. Таким образом, изначально ваши элементы указывают на пустой массив, там array.map работал, но когда массив был изменен на объект (когда данные были извлечены и было вызвано setState), у него больше не было функции карты, поскольку объекты не поддерживают функцию карты. Кроме того, именно по этой причине он выводится дважды, потому что в первый раз, когда компонент был смонтирован, а затем во второй раз, когда было вызвано setState и компонент был перенаправлен.
Ответ №2:
Элементы-это массив, а не объект, например [{…}, {…}] , desiredseries находится внутри объекта, а не элементов.
<ul>
{items.map(item => item.dataseries.map(ds=> (
{console.log(ds)}
)))}
</ul>