Unsplash API with React Part 2

Launch Modal

Darryl Mendonez
3 min readJun 28, 2020
Photo by Guilherme Vasconcelos on Unsplash

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-headerunless 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 😊

Next up, adding a Search feature

--

--