I'm new to React, and trying to design an app performs a simple API call, updates the state, and conditionally renders a set of images based on the state.
I'm confused about how lifecycle methods work. According to this example,
Rendering react component after api response, the API calls are supposed to be handled in componentDidMount()
, and then DOM nodes based on the state are supposed to be handled in render()
.
However, I am confused because the React documentation says that componentDidMount()
occurs after render()
. So wouldn't it make sense to do the API call before the DOM nodes are rendered?
Regardless, in the example below, the default state is not being changed. handlePictures()
is supposed to use the dogs
api call to generate a set of pictures that will go in this.state.pictures
. However, this is not happening. When I run the code on my local machine, an error occurs when I run this.createIMGs()
in the render()
method: it says that this.state.pictures
is undefined, which leads me to guess that the API call was never made.
The API I am using is here: https://dog.ceo/dog-api/documentation/breed I am using the "multiple images from a breed collection" API, located at the bottom of the page.
//api call
const dogs = async function(breed) {
const dogsAPI = `https://dog.ceo/api/breed/${breed}/images/random/20`;
const dogs = await fetch(dogsAPI);
const json = await dogs.json();
return json.message;
}
//parent component
class DogApp extends React.Component {
constructor() {
super();
this.state = {
pictures: [],
breed: 'hound'
};
}
handleBreed(breed) {
this.setState(() => ({
breed
}));
};
handlePictures() {
this.setState(() => ({
pictures: dogs(this.state.breed)
}));
};
createIMGs() {
this.state.pictures.map((picture) => (
<img src={picture} alt="dog" />
));
};
componentDidMount() {
this.handlePictures();
}
render() {
return (
this.createIMGs();
);
}
}
ReactDOM.render( <DogApp / > , document.getElementById('app'));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Dogs</title>
<link rel="icon" type="image/png" href="/images/favicon.png">
</head>
<body>
<div id="app"></div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
</html>