@Nik_1011

Почему не удаётся получить данные из API в React?

Делаю погодное приложение, все данные из API получаю, но только стоит прописать переменную const cTemp = data.main.temp;, как всё слетает (Uncaught TypeError: Cannot read properties of undefined (reading 'temp')).

Хотя const cTemp = data.main; работает отлично. Складывается впечатление, как будто в первом варианте данные не успевают подгрузиться.

Вот весь код:
import React from 'react';
import axios from 'axios';

function App() {
  const [data, setData] = React.useState({});
  const [location, setLocation] = React.useState('');
  const [lat, setLat] = React.useState(0);
  const [long, setLong] = React.useState(0);
  const [tempSwap, setTempSwap] = React.useState(false);

  const cTemp = data.main.temp.toFixed();
  // const fTemp = ((cTemp * 9) / 5 - 459.67);

  const url = `https://api.openweathermap.org/data/2.5/weather?${
    location ? `q=${location}` : `lat=${lat}&lon=${long}`
  }&units=metric&appid=key`;

  React.useEffect(() => {
    const fetchData = async () => {
      navigator.geolocation.getCurrentPosition((position) => {
        setLat(position.coords.latitude);
        setLong(position.coords.longitude);
      });

      await axios.get(url).then((response) => {
        setData(response.data);
      });
    };
    fetchData();
  }, [lat, long]);

const searchLocation = (event) => {
    if (event.key === 'Enter') {
      axios.get(url).then((response) => {
        setData(response.data);
      });
      setLocation('');
    }
  };

  return (
    <div className="app">
      <div className="search">
        <input
          value={location}
          onChange={(event) => setLocation(event.target.value)}
          onKeyPress={searchLocation}
          placeholder="Enter Location"
          type="text"
        />
      </div>

 <div className="container">
        <div className="top">
          <div className="location">
            <p>{data.name}</p>
            {console.log(cTemp)} // Вывод пробую сделать
          </div>
          <div className="temp">{data.main ? <h1>{data.main.temp.toFixed()}°F</h1> : null}</div>
          <div className="description">{data.weather ? <p>{data.weather[0].main}</p> : null}</div>
        </div>

        {data.name !== undefined && (
          <div className="bottom">
            <div className="feels">
              {data.main ? <p className="bold">{data.main.feels_like.toFixed()}°F</p> : null}
              <p>Feels like</p>
            </div>
            <div className="humidity">
              {data.main ? <p className="bold">{data.main.humidity}%</p> : null}
              <p>Humidity</p>
            </div>
            <div className="wind">
              {data.wind ? <p className="bold">{data.wind.speed.toFixed()} MPH</p> : null}
              <p>Wind Speed</p>
            </div>
          </div>
        )}
      </div>
    </div>
);
}

export default App;
  • Вопрос задан
  • 127 просмотров
Решения вопроса 1
fleshherbal
@fleshherbal
Уберите строку "const cTemp = data.main.temp.toFixed();" Так как она инициализируется быстрее, чем приходит ответ с АПИ. Соответственно не может найти.

Для этого используйте useEffect(()=>{ }, [data]);

let cTemp = 0;

useEffect(() => {
       if(data.main) cTemp = data.main.temp.toFixed();
}, [data])


или инициализируйте начальное состояние: useState({main: {temp: 0}});
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
22 нояб. 2024, в 12:53
25000 руб./за проект
22 нояб. 2024, в 12:20
10000 руб./за проект
22 нояб. 2024, в 11:53
3000 руб./за проект