Реакция выборки данных из API выдает ошибку Невозможно прочитать свойство undefined - PullRequest
0 голосов
/ 11 апреля 2020

Я использую React Hook для извлечения данных из объекта JSON с использованием собственного метода выборки.

const COVID_API_URL = "https://api.covid19api.com/summary";
const [infected, setInfected] = useState([]);

async function fetchData() {
  const response = await fetch(COVID_API_URL);

  response.json().then(response => setInfected(response));
}

useEffect(() => {
  fetchData();
}, []);

console.log(infected.Global.TotalConfirmed);

Когда я console.log значение из TotalConfirmed, я получаю правильный результат , но когда я обновляю sh браузер, я получаю:

TypeError: Cannot read property 'TotalConfirmed' of undefined

Кто-нибудь знает, почему это происходит? Я использую Gatsby. js Стандартный стартер, это как-то связано с этим?

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Проблема в том, что значение для infected состояния поступает асинхронно . То, что вы можете сделать, это использовать useEffect hook.

Попробуйте сделать следующее:

useEffect(() => {
   console.log(infected.Global.TotalConfirmed);
}, [infected]);

При этом useEffect обратный вызов будет запущен при изменении значения infected - API ответы на вызовы - поэтому после setInfected(response) обновляет значение infected состояние.

Надеюсь, это поможет!

0 голосов
/ 11 апреля 2020

При первом обращении к infected оно все еще не определено, все, что вам нужно сделать, это проверить переменную перед ее использованием. Вам не нужно еще useEffect.

console.log(infected && infected.Global && infected.Global.TotalConfirmed);

const {useState, useEffect} = React;

const COVID_API_URL = "https://api.covid19api.com/summary";

function App() {
  const [infected, setInfected] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  function fetchData() {
    fetch(COVID_API_URL)
      .then(jsonResponse => jsonResponse.json())
      .then(response => {
        setIsLoading(false);
        setInfected(response);
      })
      .catch(e => {
        console.log("error", e);
        setIsLoading(false);
      });
  }

  useEffect(() => {
    fetchData();
  }, []);

  console.log(infected && infected.Global && infected.Global.TotalConfirmed);
  return (
    <div className="App">
      <h1>COVID-19 Summary</h1>
      {isLoading && <p>Getting data...</p>}
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById("app")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...