Unsplash API with React Part 2
Launch Modal
Welcome back. Let us continue building our Unsplash-like React App. During our last round, we’ve successfully fetched our data from the Unsplash API, set our state with the returned results, and rendered a gallery of thirty images all on page load.
We’ll continue with setting up an onClick
function that fires when a user clicks a thumbnail which will then launch a modal that displays a full res version of the image along with a description. In our App
component’s constructor
function where we initialized the state, let’s add another property called selectedImage
like so:
constructor(props) {
super(props)
this.state = {
gallery: [],
searchedQuery: '',
selectedImage: {
description: '',
src: '',
username: '',
page: '',
},
}
}
This object will be used to get all the data we need for the content of our modal. Let’s also set up our launchModal
function in our App
component.
launchModal = (index) => {
this.setState((prevState) => {
return {
selectedImage: {
description: prevState.gallery[index].description,
src: prevState.gallery[index].urls.regular,
username: prevState.gallery[index].user.username,
page: prevState.gallery[index].user.links.html,
}
}
})
}
As you can see, we’ll pass in an index
which will be done in the onClick
event. We’ll then set our state asynchronously passing in the prevState
and assigning the properties of the selectedImage
to their corresponding properties of the current item in the the prevState
's gallery
by using the index
. Notice this time we’re using the regular
url for the src
property where as we used the small
property when we set up our page’s gallery thumbnails. We can now pass this function as a prop to our Gallery
component as well as our selectedImage
object like so:
<Gallery gallery={this.state.gallery} launchModal={this.launchModal} selectedImage={this.state.selectedImage} />
Let’s now move on to creating a popup modal for when a user selects an image. We can leverage Bootstrap for its modal (and later its navbar and input form for our search feature) by installing via npm or cdn. We’ll also take the modal template snippet from Bootstrap and paste it into our Gallery
component right below the section
end tag. Don’t forget to change all of the class
attributes to className
since we are writing JSX and technically not HTML. You may not need the div.modal-header
unless you want to add a title to the modal. Feel free set up the modal like so or however you like:
<div className="modal fade" id="selected-img-modal" tabIndex="-1" role="dialog" aria-labelledby="selected-img-modal-label" aria-hidden="true">
<div className="modal-dialog modal-lg" role="document">
<div className="modal-content">
<div className="modal-body">
<img src={selectedImage.src} alt={selectedImage.description} />
<hr/>
<p>{selectedImage.description}</p>
<p>Photo by <a href={selectedImage.page + `?utm_source=find-inspiration`} target="_blank" rel="noopener noreferrer">{selectedImage.username}</a> on <a href="https://unsplash.com/?utm_source=find-inspiration`" target="_blank" rel="noopener noreferrer">Unsplash</a></p>
</div>
</div>
</div>
</div>
Great, so now we have our modal template set up. We have the src
and alt
attributes of the img
tag binded as well as a description and credit to the photographer and Unsplash which is not required per their license page but it is nice to do. Now we have to accept our launchModal
function and set it up as a click event on each thumbnail. Along with destructuring gallery
from our props
let’s also add in launchModal
and selectedImage
. We also need to add some data attributes and an onClick
event listener to the img
tag:
const Gallery = (props) => {
const { gallery, launchModal, selectedImage } = props
.
.
.
<img
src={image.urls.small}
alt={image.description}
data-toggle="modal"
data-target="#selected-img-modal"
onClick={() => launchModal(index)}
/>
.
.
.
}
Great, you should now be able to click on a thumbnail to view a larger res version of the image 😊