Я хочу сделать приложение Weather. Я только начинаю изучать реакцию. Я делаю запрос на получение данных к Open Weather API, чтобы получить данные о погоде. Когда я consol.log(data) и обновляю свою страницу, React сначала возвращает мне неопределенное значение, а после этого данные. Я не могу использовать данные в других компонентах, поскольку данные не определены.
Приложение.jsx
function App() {
const [weatherData, setWeatherData] = useState()
useEffect(()=>{
requestWeather('London')
}, [])
let requestWeather = async (city)=> {
try {
const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=4e4ff6f3165d9a027265ab73068e5a3a&mode=JSON`
fetch(url)
.then(data => data.json())
.then(data => {
setWeatherData(data)
})
} catch (error) {
console.info(error);
}
}
console.info(weatherData);
return (
<>
<div className = "wrapper">
<Weather weather_data = {weatherData}/>
</div>
</>
)
}
Погода.jsx
export default function Weather({weather_data}){
return(
<div>{weather_data.name}</div>
// There '.name' display name of city
)
}
Когда я запускаю это, я получаю эти ошибки ОШИБКИ
Для состояния не указано значение по умолчанию:
const [weatherData, setWeatherData] = useState();
По умолчанию это undefined
. Вы можете добавить любое значение по умолчанию, которое вам нравится. Например, по умолчанию это будет пустой объект:
const [weatherData, setWeatherData] = useState({});
Или вы не можете визуализировать компонент Weather
, если значение «ложное»:
<div className = "wrapper">
{ weatherData ? <Weather weather_data = {weatherData}/> : null }
</div>
Или вы можете обработать undefined
внутри самого компонента Weather
:
<div>{weather_data?.name}</div>
Не имеет отношения к делу, но вы также захотите выработать привычку завершать операторы точкой с запятой. JavaScript прощает пропуск точек с запятой, но программистам этого делать не следует. Это одна из тех вещей, которые будут работать нормально до тех пор, пока не перестанут работать.
Как я могу объединить {данные? <Item data = {data}/> : null} и .map(). Пример: у меня есть массив с объектами. Я хочу выполнить .map() для массива, отправить каждый объект object.key в элемент и отобразить его столько раз, сколько элементов в массиве?
@HelpMeStudy: Что мешает вам использовать .map() в вашем массиве? Если вы предприняли какую-то попытку что-то сделать, и это не сработало каким-то конкретным образом, то, вероятно, стоит опубликовать вопрос о переполнении стека.
Когда ваш компонент выполняет рендеринг, он выполняет вызов API для получения данных о погоде, поэтому до тех пор, пока ваш вызов успешно не получит данные о погоде и не установит их в состояние, ваши данные WeatherData не определены.
Решение, предложенное Дэвидом, также справедливо.
Мое предложение состояло бы в том, чтобы не отображать ваш компонент Weather до тех пор, пока данные не будут успешно загружены и сохранены в следующем виде:
function App() {
const [weatherData, setWeatherData] = useState();
const [isWeatherDataLoading, setIsWeatherDataLoading] = useState(true);
const [weatherLoadingError, setWeatherLoadingError] = useState(null);
useEffect(() => {
requestWeather("London");
}, []);
const requestWeather = (city) => {
setIsWeatherDataLoading(true);
setWeatherLoadingError(null);
const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=4e4ff6f3165d9a027265ab73068e5a3a&mode=JSON`;
fetch(url)
.then((data) => data.json())
.then((data) => {
setWeatherData(data);
})
.catch((error) => {
setWeatherLoadingError(JSON.stringify(error));
})
.finally(() => {
setIsWeatherDataLoading(false);
});
};
if (isWeatherDataLoading) {
return (
<div className = "wrapper">
<div>Loading weather</div>
</div>
);
}
if (weatherLoadingError) {
return (
<div className = "wrapper">
<div>Failed to load weather data with error: {weatherLoadingError}</div>
<button onClick = {() => requestWeather("London")}>Try again</button>
</div>
);
}
return (
<div className = "wrapper">
<Weather weather_data = {weatherData} />
</div>
);
}
Аналогичным образом: Не имеет отношения к делу, но вы также захотите выработать привычку обрабатывать состояния загрузки и ошибок в своих приложениях React. Интервьюер может быть прощающим, но пользовательская история не должна быть такой.
В обновленном вопросе показанные (изображения) ошибки, похоже, не соответствуют изменениям, внесенным в код. (Кроме того, я также не согласен с выбранным дубликатом. Этот вопрос не возвращается из асинхронной операции. Если не считать ненужного использования
async
в этой функции, асинхронный код правильный.)