#reactjs #async-await #weather-api
#reactjs #асинхронный-ожидание #погода-api
Вопрос:
Я новичок в React.js , так что, пожалуйста, потерпите меня в этом вопросе.
Я создал приложение weather API с react.js и это работает. Единственное, что я не могу сделать async function fetchData(e)
, это экспортировать мой файл таким образом, чтобы я мог получить к нему доступ из любого компонента, выходящего за рамки App.js . Как мне экспортировать асинхронные данные выборки, чтобы они распознавались всеми компонентами, которые находятся за пределами App.js ? Обратите внимание, что async function fetchData(e)
для функции требуются все переменные, которые объявлены в начале App.js .
Я исключил свой ключ API из кода по понятным причинам, и я не включил весь код в функцию fetchData, потому что он очень длинный.
function App() {
//Variables
const API_KEY = '';
const METRE_SECOND_TO_KM_HR = 3.6;
const DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
};
const [weather, setWeather] = useState([]);
const [geolocation, setGeolocation] = useState([]);
async function fetchData(e) {
//async function fetchData(e) {
const city = e.target.elements.city.value;
const state = e.target.elements.state.value;
const country = e.target.elements.country.value;
e.preventDefault();
//fetch request with city, state and country - to get a latitude and longitude based on city name.
const geolocation_api_request_url = `https://api.openweathermap.org/geo/1.0/direct?q=${city},${state},${country}amp;limit=5amp;appid=${API_KEY}`;
await fetch(geolocation_api_request_url)
.then(function (res) {
return res.json();
})
.then(function (data) {
if (city amp;amp; state amp;amp; country) {
//set the latitude and longitude of the location
setGeolocation({
data: data,
lat: data[0].lat,
lon: data[0].lon,
});
//make a second fetch call, this time with latitude and longitude
const weather_api_url = `https://api.openweathermap.org/data/2.5/onecall?lat=${geolocation.lat}amp;lon=${geolocation.lon}amp;exclude=minutely,hourlyamp;appid=${API_KEY}amp;units=metric`;
return fetch(weather_api_url);
}
})
Ответ №1:
Попробуйте выполнить следующее.
— WeatherAPI.js —
const fetchData = (city, state, country, setGeolocation) => {
return new Promise(async(resolve, reject)=>{
const geolocation_api_request_url = `https://api.openweathermap.org/geo/1.0/direct?q=${city},${state},${country}amp;limit=5amp;appid=${API_KEY}`;
try{
res = await fetch(geolocation_api_request_url);
if(city amp;amp; state amp;amp; country){
//set the latitude and longitude of the location
const data = res.json();
setGeolocation amp;amp; setGeolocation({
data: data,
lat: data[0].lat,
lon: data[0].lon,
});
//make a second fetch call, this time with latitude and longitude
const weather_api_url = `https://api.openweathermap.org/data/2.5/onecall?lat=${geolocation.lat}amp;lon=${geolocation.lon}amp;exclude=minutely,hourlyamp;appid=${API_KEY}amp;units=metric`;
resolve(await fetch(weather_api_url));
}
}catch(e){
reject(e);
}
});
}
export fetchData;
— App.js —
import {fetchData} from '../api/WeatherAPI";
...
function fetchDataFromGoogle(e) {
...
(async()=>{
try{
const weatherData = await fetchData(city, state, country, setGeolocation);
}catch(e){
console.error(e);
}
})();
}
Ответ №2:
https://reactjs.org/docs/context.html#updating-context-from-a-nested-component
взгляните на этот контекстный Api react js, используя его, вы можете получить эту функцию в любом компоненте вашего приложения, а также обновить ее значения.
Ответ №3:
Вы можете экспортировать асинхронные функции как таковые, как только вы отделите их от функции приложения:
export const fetchData = async (args) => {
// Your implementation
}
Что касается параметров, если все они являются константами, поместите их внутрь объекта json и передайте функции, поскольку экспортируемая функция не может получить доступ к этим переменным:
const args = {
API_KEY : '',
METRE_SECOND_TO_KM_HR : 3.6,
DAYS : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
options : {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
}
и передать этот объект функции в качестве параметра:
export const fetchData = async (e, args) => {
// Your implementation
}
Комментарии:
1. Спасибо за ваш ответ. Я попытался выполнить экспорт таким образом, я получаю эту ошибку: «импорт» и «экспорт» могут отображаться только на верхнем уровне (44: 2) 2)
2. это не может работать, потому что вы уже находитесь в функции приложения
3. о, мой плохой был ленив, обращая внимание, да, вам нужно разделить два, к сожалению
4. Спасибо, Синан, все в порядке, не могли бы вы объяснить, почему это не сработает? Я не понимаю, почему не получилось бы экспортировать ее внутри App.js .
5. Поскольку это функция внутри другой функции, вы можете экспортировать только в том случае, если она не находится внутри области видимости, то есть когда она находится на верхнем уровне.