При загрузке страницы я получаю данные о погоде для API, а затем отображаю их на боковой панели, а затем, когда вы нажимаете на город, он показывает погоду в городе более подробно. Итак, в основном я передаю данные от родителя к ребенку с помощью реквизита. Мне нужно заполнить подробный компонент некоторыми начальными данными, поэтому я пытаюсь отправить первый объект в массиве данных дочернему компоненту через реквизиты и установить его в состояние, но когда я пытаюсь отобразить его, он не определен, и я не понятно почему.
На самом деле, кажется, что пару раз он возвращается неопределенным, прежде чем установить его, но когда я пытаюсь отобразить его на странице {weather.data.temp}, я получаю сообщение "Невозможно прочитать свойство "temp" из неопределенного".
Родитель:
const fetchCity = async (city) => {
const res = await axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${key}`);
return {
description: res.data.weather[0].description,
icon: res.data.weather[0].icon,
temp: res.data.main.temp,
city: res.data.name,
country: res.data.sys.country,
id: res.data.id,
};
};
function App() {
const [data, setData] = useState([]);
const [activeWeather, setActiveWeather] = useState([]);
useEffect(() => {
const fetchCities = async () => {
const citiesData = await Promise.all(["Ottawa", "Toronto", "Vancouver", "California", "London"].map(fetchCity)).catch((err) => {
console.log(err);
});
setData((prevState) => prevState.concat(citiesData));
};
fetchCities();
}, []);
const handleClick = (event) => {
const weather = JSON.parse(event.target.dataset.value);
setActiveWeather(weather);
};
return (
<div className="App">
<Header />
<Container>
<Row>
<Col>
<WeatherPanel data={data} handleClick={handleClick} />
</Col>
<Col>
<ActiveWeather activeWeather={activeWeather} data={data[0]} />
</Col>
</Row>
</Container>
</div>
);
}
export default App;
Ребенок
import React, { useEffect, useState } from "react";
import { Container, Card } from "react-bootstrap";
const ActiveWeather = (props) => {
const [weather, setWeather] = useState();
useEffect(() => {
setWeather(props.data);
}, [props]);
console.log(weather);
return (
<Container>
<Card>
<Card.Header> </Card.Header>
{weather.temp}
</Card>
</Container>
);
};
export default ActiveWeather;
Другой ребенок
const WeatherPanel = (props) => {
return (
<div>
<Container fluid>
<Card style={{ boxShadow: "0 0 10px 2px lightgrey" }}>
<Card.Header> Favorite Location</Card.Header>
<ListGroup variant="flush">
<ListGroup.Item>
{props.data.map((item) => (
<ListGroup.Item key={item.id} data-value={JSON.stringify(item)} onClick={props.handleClick}>
<img src={`http://openweathermap.org/img/wn/${item.icon}@2x.png`} alt="Weather Icon" />
{item.city + ", " + item.country}
</ListGroup.Item>
))}
</ListGroup.Item>
</ListGroup>
</Card>
</Container>
</div>
);
};
export default WeatherPanel;
Эта строка —
const weather = JSON.parse(event.target.dataset.value);
— кажется мне очень странной. Почему вы используете DOM для хранения данных?По сути, у меня есть эта карта с несколькими разными городами, и когда я нажимаю на определенный город, я хочу отобразить более подробный раздел погоды в городах. Я использовал data-value, чтобы передать значение этой функции handleClick, но его нужно проанализировать, и по какой-то причине, если я проанализирую его где-нибудь, кроме app.js, это даст мне ошибку перекрестного происхождения. Я отредактировал, чтобы показать другой компонент.