Ошибка типа: Не удается прочитать свойства неопределенного (чтение «карты») при вызове из API

#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:

Есть две ошибки, которые я мог видеть

  1. Одним из них является то, что данные, которые вы извлекаете, являются объектом, в то время как вы изначально настраиваете его как массив, и вы также используете функцию карты, которая может использоваться только для массивов.
  2. Изначально ваш массив не содержит 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>