Почему не выводятся данные из fetch запроса в элементы на React?
class MyWeather extends React.Component {
constructor(props) {
super(props);
this.state = {
data: {}
};
}
componentDidMount() {
fetch('https://api.openweathermap.org/data/2.5/weather?q=ODESA&units=metric&APPID=5d066958a60d315387d9492393935c19')
.then(response => response.json())
.then(data => this.setState({ data }));
console.log(this.state.data);
}
render() {
const { data } = this.state;
const srcURL = `https://openweathermap.org/img/w/${data.weather[0]['icon']}.png`;
return (
<div>
<h1>City: {data.name}</h1>
<p>Temperature: {Math.round(data.main.temp)}°C</p>
<p>Pressure: {data.main.pressure} hPa</p>
<p>Description: {data.weather[0]['description']}</p>
<p>Humidity: {data.main.humidity}%</p>
<p>Speed: {data.wind.speed}m/s</p>
<p>Degree: {data.wind.deg}°</p>
<img src={srcURL} alt='Weather' title='Weather'/>
</div>
);
}
}
ReactDOM.render(
<MyWeather />,
document.body
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
В консоли есть ошибка:
TypeError: Cannot read properties of undefined (reading '0')
Ответы (1 шт):
Автор решения: SwaD
→ Ссылка
Ошибка вызвана тем, что при первом рендериге не проверяются значения на их существование.
Необходимо в render добавить проверку, что в this.state.data есть данные.
Допустим, в качестве примера, проверить, что в data есть ключ name:
render() {
const { data } = this.state;
if (data.name) {
const srcURL = `https://openweathermap.org/img/w/${data.weather[0]['icon']}.png`;
return (
<div>
<h1>City: {data.name}</h1>
<p>Temperature: {Math.round(data.main.temp)}°C</p>
<p>Pressure: {data.main.pressure} hPa</p>
<p>Description: {data.weather[0]['description']}</p>
<p>Humidity: {data.main.humidity}%</p>
<p>Speed: {data.wind.speed}m/s</p>
<p>Degree: {data.wind.deg}°</p>
<img src={srcURL} alt='Weather' title='Weather'/>
</div>
);
} else {
return null; // Или что то другое, говорящее, что компонент ожидает данные
}
}
В больших проектах, я бы рекоменовал избавляться в методе render от создания ненужных переменных и обращаться к this.state.data
Более красивый вариант:
render() {
const {data} = this.state;
if (!data.name) return null;
const srcURL = `https://openweathermap.org/img/w/${data.weather[0]['icon']}.png`;
return (
<div>
<h1>City: {data.name}</h1>
<p>Temperature: {Math.round(data.main.temp)}°C</p>
<p>Pressure: {data.main.pressure} hPa</p>
<p>Description: {data.weather[0]['description']}</p>
<p>Humidity: {data.main.humidity}%</p>
<p>Speed: {data.wind.speed}m/s</p>
<p>Degree: {data.wind.deg}°</p>
<img src={srcURL} alt='Weather' title='Weather'/>
</div>
);
}

