我需要以下序列的解决方案:
浏览器检查用户的地理位置(假设他允许( ->经度和纬度保持状态并用于 2 次 API 调用 -> 谷歌反向地理位置 API 检查城市名称,同时 DarkSky API 检查天气 ->第三个 API 等待先前调用的结果,并将其用作第三个调用的查询, 未飞溅的 API
这是我的代码:
const [position, setPosition] = useState({ latitude: '50.049683', longitude: '19.944544' });
const [info, setInfo] = useState({ city: null, weather: null });
const [photos, setPhotos] = useState([]);
useEffect(() => {
const fetchInfo = async () => {
try {
const [cityInfo, weatherInfo] = await Promise.all([
axios.get(
`https://maps.googleapis.com/maps/api/geocode/json?latlng=${position.latitude},${position.longitude}&language=en&result_type=locality&key=${GEO_ACC_KEY}`,
),
axios.get(
`https://api.darksky.net/forecast/${WEATHER_ACC_KEY}/${position.latitude},${position.longitude}?exclude=hourly,daily,alerts,flags`,
),
]);
setInfo({
city: cityInfo.data.results[0].address_components[0].short_name,
weather: weatherInfo.data.currently.summary.toLowerCase(),
});
console.log('Info', info); // Results in {city: null, weather: 'null'}
const photosData = await axios.get(
`https://api.unsplash.com/search/photos?query=${info.weather}+${info.city}&page=1&per_page=8&client_id=${UNSPLASH_ACC_KEY}`,
);
setPhotos(photosData.data.results);
console.log('Photos data from API call:', photosData); //Object based on query: "null+null"
console.log('Photos:', photos); // Empty array
} catch (err) {
// Handling errors
}
};
fetchInfo();
}, []);
console.log('Info outside axios get', info); // Results in object with city name and current weather
console.log('photos outside axios get', photos); // Proper result I am looking for
目前,正确的数据仅在使用效果之外可用。它不提供第三个 API 调用的数据(现在 Unsplash API 调用使用"null+null"作为查询(。
所以我转到 useEffect 文档,它说第二个参数(数组(接受依赖项并在任何状态依赖项更改时更新。
我尝试按如下方式使用它:
useEffect(() => {
const fetchInfo = async () => {
//rest of the code
},
fetchInfo();
}, [info]);
它使用 API 调用的正确关键字(城市和天气,而不是空 null(,但创建无限的 API 调用。
我该如何解决这个问题?
状态更新不会立即更新,并将反映在下一个呈现周期中。
请查看这篇文章以获取更多详细信息:useState set 方法不会立即反映更改
此外,您必须注意,您希望链接 API 调用,而不是在信息更改时再次调用整个 useEffect。将info
添加为依赖项肯定会导致无限循环,因为info
是在useEffect中设置的。
要解决您的问题,您可以改用在进行 api 调用时设置为声明的值
const newInfo = {
city: cityInfo.data.results[0].address_components[0].short_name,
weather: weatherInfo.data.currently.summary.toLowerCase(),
}
setInfo(newInfo);
console.log('Info', info); // Results in {city: null, weather: 'null'}
const photosData = await axios.get(
`https://api.unsplash.com/search/photos?query=${newInfo.weather}+${newInfo.city}&page=1&per_page=8&client_id=${UNSPLASH_ACC_KEY}`,
);