Я хочу сделать приложение 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
)
}
Когда я запускаю это, я получаю эти ошибки ОШИБКИ
🤔 А знаете ли вы, что...
JavaScript может выполняться как на стороне клиента (в браузере), так и на стороне сервера (с использованием Node.js).
Для состояния не указано значение по умолчанию:
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 прощает пропуск точек с запятой, но программистам этого делать не следует. Это одна из тех вещей, которые будут работать нормально до тех пор, пока не перестанут работать.
Когда ваш компонент выполняет рендеринг, он выполняет вызов 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. Интервьюер может быть прощающим, но пользовательская история не должна быть такой.