Мне нужны данные из вызова API 1 для добавления к URL-адресу вызова API 2. Данные из API 2 перейдут в URL-адрес для API 3. Я устанавливаю состояние для каждого запроса Axios, и оно не работает. Возврат неопределенного
componentDidMount() {
// Get the IP adress of user
axios
.get('https://api.ipify.org?format=json')
.then(res => {
this.setState({
ip: res.data.ip
});
console.info(`IP : ${this.state.ip}`);
})
.catch(err => console.info(err));
// GET the coordinates of a location based on IP adress
axios
.get(
'https://geo.ipify.org/api/v1?apiKey=YOUR_API_KEY&ipAddress=24.8.227.87'
)
.then(res => {
this.setState({
latitude: res.data.location.lat,
longitude: res.data.location.lng
});
console.info(
`Latitude: ${this.state.latitude}. Longitude: ${this.state.longitude}`
);
})
.catch(err => console.info(err));
// Make the API call on page load
axios({
method: 'get',
url: `https://developers.zomato.com/api/v2.1/geocode?lat=39.6924553&lon=-105.0256318`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
'user-key': 'USER_KEY'
}
})
.then(res => {
const restaurantsNearMe = res.data.nearby_restaurants;
this.setState({
restaurants: restaurantsNearMe
});
// Pick out a random retaurant from what the API returns
var randomRestaurant =
restaurantsNearMe[
Math.floor(Math.random() * restaurantsNearMe.length)
];
// Select only the data that you want
var finalResult = {
name: randomRestaurant.restaurant.name,
id: randomRestaurant.restaurant.id,
rating: randomRestaurant.restaurant.user_rating.aggregate_rating,
ratingColor: randomRestaurant.restaurant.user_rating.rating_color,
address: randomRestaurant.restaurant.location.address,
delivery: randomRestaurant.restaurant.is_delivering_now,
typeOfFood: randomRestaurant.restaurant.cuisines
};
this.setState({
restaurant: finalResult
});
console.info(this.state.restaurant);
})
.catch(err => console.info(err));
}
нужно иметь в виду, что this.setState не является синхронным. React объединяет несколько вызовов set state для повышения производительности рендеринга. Вот почему вы можете видеть undefined в console.info. Метод setState принимает обратный вызов в качестве второго параметра.
this.setState(newState, callbalck)
поэтому попробуйте войти в консоль обратного вызова и попробовать.
Я не знаю, как вы вызываете API, но попробуйте что-то вроде этого:
В componentDidMount
вы можете сделать это:
async componentDidMount(){
const resApiOne = await callFirstApi();
this.setState({resApiOne});
const resApiTwo = await callSecondApi(resApiOne);
this.setState({resApiTwo});
}
Вам нужен callback
в setState
, а в этом callback
нужно вызвать второго API
и так далее. Проверьте это.
Это то, что вы хотите,
axios
.get('https://api.ipify.org?format=json')
.then(res => {
this.setState({
ip: res.data.ip
}, () => {
// GET the coordinates of a location based on IP adress
axios
.get(
'https://geo.ipify.org/api/v1?apiKey=YOUR_API_KEY&ipAddress=24.8.227.87'
)
.then(res => {
this.setState({
latitude: res.data.location.lat,
longitude: res.data.location.lng
}, () => {
// Make the API call on page load
axios({
method: 'get',
url: `https://developers.zomato.com/api/v2.1/geocode?lat=39.6924553&lon=-105.0256318`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
'user-key': 'USER_KEY'
}
})
.then(res => {
const restaurantsNearMe = res.data.nearby_restaurants;
this.setState({
restaurants: restaurantsNearMe
});
// Pick out a random retaurant from what the API returns
var randomRestaurant =
restaurantsNearMe[
Math.floor(Math.random() * restaurantsNearMe.length)
];
// Select only the data that you want
var finalResult = {
name: randomRestaurant.restaurant.name,
id: randomRestaurant.restaurant.id,
rating: randomRestaurant.restaurant.user_rating.aggregate_rating,
ratingColor: randomRestaurant.restaurant.user_rating.rating_color,
address: randomRestaurant.restaurant.location.address,
delivery: randomRestaurant.restaurant.is_delivering_now,
typeOfFood: randomRestaurant.restaurant.cuisines
};
this.setState({
restaurant: finalResult
});
console.info(this.state.restaurant);
})
.catch(err => console.info(err));
});
console.info(
`Latitude: ${this.state.latitude}. Longitude: ${this.state.longitude}`
);
})
.catch(err => console.info(err));
});
console.info(`IP : ${this.state.ip}`);
})
.catch(err => console.info(err));
Проверьте цепочку промисов: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…. Это функция, которую вы ищете, и в статье MDN объясняется, почему некоторые фрагменты состояния не определены, когда кажется, что они не должны быть.