React: Working With API’s, Mapping Arrays & Looping Images
Series
This is part 1/3 in a series making a responsive masonry image grid in React, with images pulled from Unsplash using an API, queried from a text input in a small sample app.
Making An API Request
React doesn’t actually have any built in functionality for working with API so we will be looking at how to integrate common methods of fetching data INTO React and how those items work together.
Common ways to accomplish this include using fetch() or Axios. We will start by going over the process with Axios.
Get it installed in your project and then come back.
From there is actually really simple to make a basic query. We have our basic App component that we are working with here that is getting an input fed into it from the SearchBar child component.
Then we have our function onSearchSubmit that executes when the user submits their query to the text input child component. We call the .get method on axios, and then following the axios and Unsplash API documentation we submit the parameters of our request and our authorization in the header. I’ve redacted my authorization key here. Later on we will be replacing it with an environment variable.
class App extends React.Component {
onSearchSubmit(input) {
axios.get("https://api.unsplash.com/search/photos", {
params: {
query: input,
},
headers: {
Authorization: "Client-ID your-authorization-key",
},
});
}
render() {
return (
<div className="ui container" style={{ marginTop: "10px" }}>
<SearchBar onSubmit={this.onSearchSubmit} />
</div>
);
}
}
Working With Returned Data
.then()
Because axios works with Promises we are able to use the .then
method as one way to do something with our retrieved data.
class App extends React.Component {
onSearchSubmit(input) {
axios
.get("https://api.unsplash.com/search/photos", {
params: {
query: input,
},
headers: {
Authorization:
"Client-ID your-authorization-key",
},
})
.then((response) => {
console.log(response.data.results);
});
}
render() {
return (
<div className="ui container" style={{ marginTop: "10px" }}>
<SearchBar onSubmit={this.onSearchSubmit} />
</div>
);
}
}
You can read more about the .then method here:
Async Await
This would be my preferred method, which is to use Async Await. We simply convert the function to an Async function and then await the response from the API.
class App extends React.Component {
async onSearchSubmit(input) {
const response = await axios.get("https://api.unsplash.com/search/photos", {
params: {
query: input,
},
headers: {
Authorization: "Client-ID your-authorization-key",
},
});
console.log(response.data.results);
}
render() {
return (
<div className="ui container" style={{ marginTop: "10px" }}>
<SearchBar onSubmit={this.onSearchSubmit} />
</div>
);
}
}
Set State
The next thing to do is initialize state with a blank array of images, and then set the state of that array to the array of photos once it has arrived. Note that we also have to refactor the onSearchSubmit
function with an arrow function to avoid the “this is undefined”.
Then in our render method we can output the number of images that are found to get some initial feedback up on our screen before we make our display loop.
class App extends React.Component {
state = { images: [] };
onSearchSubmit = async (input) => {
const response = await axios.get("https://api.unsplash.com/search/photos", {
params: { query: input },
headers: {
Authorization: "Client-ID your-authorization-key",
}
});
this.setState({ images: response.data.results });
}
render() {
return (
<div className="ui container" style={{ marginTop: "10px" }}>
<SearchBar onSubmit={this.onSearchSubmit} />
Found: {this.state.images.length} images
</div>
);
}
}
Creating Custom Axios Client
Before moving on let us do a bit of a refactor here. We have a lot of configuration code inside of our App component which is bad practice. Let’s create a custom client for the Unsplash API. First we can make a new directory in our base index called API and we can put any API configuration files inside of that directory.
inside our custom unsplash client we can place the following
import axios from 'axios';
export default axios.create({
baseURL: 'https://api.unsplash.com',
headers: {
Authorization: "Client-ID S4bzmlXtaBM7r_gDs6gVZDxsADGoS7jvMxbsfI7aueI",
}
});
And then we can import this client into the App component and remove the configuration data from the component.
import React from "react";
import unsplash from "../API/unsplash";
import SearchBar from "./SearchBar";
class App extends React.Component {
state = { images: [] };
onSearchSubmit = async (input) => {
const response = await unsplash.get("/search/photos", {
params: { query: input },
});
this.setState({ images: response.data.results });
};
render() {
return (
<div className="ui container" style={{ marginTop: "10px" }}>
<SearchBar onSubmit={this.onSearchSubmit} />
Found: {this.state.images.length} images
</div>
);
}
}
export default App;
We could have placed the whole request inside of the custom client, but this structure will serve us better when we get to more complicated projects.
Looping Over and Displaying the Image Array
Passing in the Array
First we need to scaffold out a new component which we will call ImageList. Then we need to pass our array of images that we have received from unsplash into this component as a prop, and then do… something. Let’s go ahead and get that array passed into the new component first.
class App extends React.Component {
state = { images: [] };
onSearchSubmit = async (input) => {
const response = await unsplash.get("/search/photos", {
params: { query: input },
});
this.setState({ images: response.data.results });
};
render() {
return (
<div className="ui container" style={{ marginTop: "10px" }}>
<SearchBar onSubmit={this.onSearchSubmit} />
<ImageList images={this.state.images} />
</div>
);
}
}
Looking at our render method we can see the new component ImageList that we have created and the prop called images where we have passed in the array. Now lets head over to our new component and manipulate that array.
Looping Over the Array With .map
The .map
method is a vanilla JS method that creates a new array, by taking an array, looping over it and manipulating each item in the array somehow. In this case we want to create a new array where every item in the array is an image with the URL of the image that we want.
We then take that new array called images
and return it for display in the App component.
const ImageList = (props) => {
console.log(props.images);
const images = props.images.map((image) => {
return <img src={image.urls.small} />;
});
return <div>{images}</div>;
};
Comments
Recent Work
Basalt
basalt.softwareFree desktop AI Chat client, designed for developers and businesses. Unlocks advanced model settings only available in the API. Includes quality of life features like custom syntax highlighting.
BidBear
bidbear.ioBidbear is a report automation tool. It downloads Amazon Seller and Advertising reports, daily, to a private database. It then merges and formats the data into beautiful, on demand, exportable performance reports.