I am trying to learn react and created a sample app that pulls random dog pictures in from the dog.ceo API.
By default a random image of any dog from any breed is returned. However, there is also a list of breeds that comes from the same API that the user can click to switch the breed they want to see.
So in the BreedList component when someone clicks on one of the breeds the breed they selected is sent back up to the App component using the handleBreedChange() event. This same function then sets the dogBreed state and calls back another function (this.getRandomImage()) to display the actual image using the new dog Breed state.
handleBreedChange(e) {
//this.setState({ dogURL: e });
var CurrentURL = `https://dog.ceo/api/breed/${e}/images/random`;
this.setState({ dogBreed: e });
this.setState({ dogURL: CurrentURL });
console.log(e);
console.log(this.state);
this.getRandomImage();
}
However, I'm running into a weird issue where on the first call the dogBreed state is not updated. It only updates on the second call (the user needs to make 2 actions before the state is current). So when the page is loaded dogBreed is blank. When a breed is clicked it stays blank on the first event call and only updates on the second one.
I read an article on how state updates are async so I imagine that has something to do with it: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
But I'm not sure how to ensure that the state is fully updated before calling the getRandomImage function (assuming that's actually my issue).
Here is my full code on Codesandbox: https://codesandbox.io/p/github/Pawel-IT/thinking_in_react/main?file=%2Fsrc%2FApp.js
Edit:
Based on what Ray suggested below I passed the expected URL as a argument to the getRandomImage function and if it's set use that instead of the state and that works. Thanks Ray! Is this the best way to do it? Would be nice is there was some function that forced the state to be updated? Or should I not be using the state for this at all?
handleBreedChange(e) {
//this.setState({ dogURL: e });
var CurrentURL = `https://dog.ceo/api/breed/${e}/images/random`;
this.setState({ dogBreed: e });
this.setState({ dogURL: CurrentURL });
console.log(e);
console.log(this.state);
this.getRandomImage(e);
}
getRandomImage(breed) {
var breedURL = this.state.dogURL;
if (breed) {
breedURL = `https://dog.ceo/api/breed/${breed}/images/random`;
}
axios.get(breedURL).then((response) => {
//setPosts(response.data);
this.setState({ message: response.data.message });
});
}