Creating an amazing Image search app using Unsplash API with infinite scrolling ๐Ÿ“ธ

Creating an amazing Image search app using Unsplash API with infinite scrolling ๐Ÿ“ธ

Learn Unsplash API, Axios and infinite scrolling!

ยท

5 min read

Hello Folks ๐Ÿ‘‹

This is Savio here. I'm young dev with an intention to enhance as a successful web developer. I love building web apps with React. I have proved my superiority in frontend technologies.

Today, I'm super pumped to build an amazing Image search app using Unsplash API with infinite scrolling. So, let's get started โœŒ


Table of contents

Setting up Unsplash API

  1. To set up Unsplash API for your app, head over to https://unsplash.com/developers and create an account scrnli_4_9_2021_11-00-46 AM.png

  2. After creating an account, go to your apps section. Here you could see your app. Now, create a new app by clicking New Application button. scrnli_08_04_2021_20-25-06.png

  3. Now accept all terms, this would create an app for you scrnli_08_04_2021_20-26-00.png

  4. You will be redirected to your app, here when you scroll you can see a section called Keys ๐Ÿ”‘. Here you can see your access key, just save it for later. We are gonna use this. scrnli_08_04_2021_20-26-57.png

Let's Start Coding

So, it is time to get into coding our app. So, take your coffee and start coding! โšก First of all, let's create a react app by copy-pasting this code in the terminal.

npx create-react-app markdown-editor

Getting Into the project directory

cd markdown-editor/

Here are the dependencies that we use for our project ๐Ÿ‘ฉโ€๐Ÿ’ป

  1. Axios
  2. react-infinite-scroll-component

Let's install all the dependencies using NPM.

npm i axios react-infinite-scroll-component

Starting our server โœจ

npm start

Now we can see our app running in localhost:3000

welcome-to-react.png

Now, we can clear some unwanted files in our src/ folder. (this is optional). I am removing all the files except App.js, index.js and index.css. I am also clearing the default code.

So, let's first start with App.js. We can create 2 variables, this would help in fetching images using Unsplash API ๐Ÿ“ธ

const client_id = "YOUR_ACCESS_KEY";
const fetchUrl = `https://api.unsplash.com/search/photos?client_id=${client_id}&query=${query}&page=${page}`;

and next we're setting some useState hooks.

const [data, setData] = useState([]);
const [query, setQuery] = useState("code");
const [page, setPage] = useState(1);
const [hasMore, setHasMore] = useState(true);

Now, create a function to fetch Images through Unsplash API. We are also gonna use axios that make the work faster. We are also increasing the page number after a load setPage(page + 1), this act important for infinite scrolling. Here goes the desired function ๐Ÿ‘‡

const fetchImages = () => {
    axios
      .get(fetchUrl, {
        headers: {},
      })
      .then((response) => {
        setData([...data, ...response.data.results]);
      })
      .catch((error) => {
        console.log(error);
      });
    setPage(page + 1);
  };

Now, lets create a useEffect hook that would run whenever query is changed. Here goes the code ๐Ÿ‘‡

useEffect(() => {
    fetchImages();
  }, [query]);

Now, lets return all our components. It consists of a input and the InfiniteScroll wrapper. Inside InfiniteScroll wrapper, we map all images. ๐Ÿ“ท

return (
    <div className="App flex">
      <input
        type="text"
        onKeyDown={(e) => searchImages(e)}
        placeholder="Search For Images ๐Ÿ”Ž"
      />
      <InfiniteScroll
        dataLength={data.length}
        next={fetchImages}
        hasMore={hasMore}
        loader={<p>Load more...</p>}
        endMessage={
          <p style={{ textAlign: "center" }}>
            <b>Yay! You have seen it all</b>
          </p>
        }
      >
        <div className="main flex">
          {data.map((data, key) => (
            <div className="container" key={key}>
              <img
                src={data.urls.small}
                className="image"
                alt={data.alt_description}
              />
              <h4>Photo by {data.user.name} ๐Ÿ“ธ</h4>
            </div>
          ))}
        </div>
      </InfiniteScroll>
    </div>
  );

We also want to update our query on every enter click on the input. For that we're gonna use a new function.

const searchImages = (e) => {
    if (e.keyCode === 13) {
      setQuery(e.target.value);
      setData([]);
    }
  };

So, the work of App.js is finished. Here goes the complete code ๐Ÿ‘‡

App.js

import axios from "axios";
import { useEffect, useState } from "react";
import InfiniteScroll from "react-infinite-scroll-component";
import "./App.css";

function App() {
  const [data, setData] = useState([]);
  const [query, setQuery] = useState("code");
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);

  const client_id = "4mB0CC1xdwTfTQGjF1v1uO9vS2Z8ubzBPd4X0B86IEU";
  const fetchUrl = `https://api.unsplash.com/search/photos?client_id=${client_id}&query=${query}&page=${page}`;

  const fetchImages = () => {
    axios
      .get(fetchUrl, {
        headers: {},
      })
      .then((response) => {
        setData([...data, ...response.data.results]);
      })
      .catch((error) => {
        console.log(error);
      });
    setPage(page + 1);
  };
  const searchImages = (e) => {
    if (e.keyCode === 13) {
      setQuery(e.target.value);
      setData([]);
    }
  };

  useEffect(() => {
    fetchImages();
  }, [query]);

  return (
    <div className="App flex">
      <input
        type="text"
        onKeyDown={(e) => searchImages(e)}
        placeholder="Search For Images ๐Ÿ”Ž"
      />
      <InfiniteScroll
        dataLength={data.length}
        next={fetchImages}
        hasMore={hasMore}
        loader={<p>Load more...</p>}
        endMessage={
          <p style={{ textAlign: "center" }}>
            <b>Yay! You have seen it all</b>
          </p>
        }
      >
        <div className="main flex">
          {data.map((data, key) => (
            <div className="container" key={key}>
              <img
                src={data.urls.small}
                className="image"
                alt={data.alt_description}
              />
              <h4>Photo by {data.user.name} ๐Ÿ“ธ</h4>
            </div>
          ))}
        </div>
      </InfiniteScroll>
    </div>
  );
}

export default App;

Now, our app is working but our app lacks beauty. So, lets style our app ๐ŸŽจ.

App.css

@import url(https://fonts.googleapis.com/css?family=Poppins:100,100italic,200,200italic,300,300italic,regular,italic,500,500italic,600,600italic,700,700italic,800,800italic,900,900italic);

* {
  margin: 0;
  padding: 0;
  font-family: "Poppins", sans-serif;
}
body {
  background: #f5effc;
}
.App {
  flex-direction: column;
}
.image {
  width: 363px;
  border-radius: 5px;
  height: 240px;
}
.container {
  border-radius: 5px;
  margin: 5px;
  padding: 15px;
  box-shadow: 0 10px 40px -10px rgb(0 64 128 / 10%);
  border: 1px solid #eee;
  background: #f9fafc;
}
h4 {
  font-weight: 400;
}
.flex {
  display: flex;
  align-items: center;
  justify-content: center;
}
.main {
  width: 100%;
  height: 100%;
  flex-wrap: wrap;
}
input {
  padding: 10px;
  box-shadow: 0 10px 40px -10px rgb(0 64 128 / 10%);
  border: 1px solid #ddd;
  background: #f9fafc;
  width: 40%;
  margin: 15px 0;
}

Congrats ๐ŸŽ‰, You have now finished working on our app. Our app is now working perfectly as expected. You did it, it was so fast! Our app now looks like this ๐Ÿ‘‡

Here is the code sandbox demo ๐Ÿ’ป

I have also deployed the app, Here goes the live demo ๐Ÿš€ https://unsplash-image-search-app.vercel.app/

Here is the full source code, don't forget to star the repository ๐ŸŒŸ https://github.com/saviomartin/unsplash-image-search-app


๐Ÿ‘€ Wrapping Up

Yeah, that's a wrap. Hope you enjoyed the article. Do not hesitate to share your feedback. I am on Twitter @saviomartin7. Give a follow!

Follow me on Github @saviomartin, Don't miss my amazing projects! ๐Ÿ’ฏ

I hope you learned to use Unsplash API and created an image search app, now go start building amazing apps. Feedbacks are greatly appreciated! ๐Ÿ™Œ

Have an amazing day!

๐ŸŒŽ Lets connect

๐Ÿ™Œ Support

My projects are fueled by coffees โ˜•, get one for me!

Did you find this article valuable?

Support Savio Martin by becoming a sponsor. Any amount is appreciated!