Tuesday, November 26, 2024
Google search engine
HomeLanguagesBuild an Image Search App with Infinite Scroll using ReactJS

Build an Image Search App with Infinite Scroll using ReactJS

In this article, we will explore how to create an image search app with infinite scroll using React. The app will allow users to search for images based on a given query, and as they scroll down, more images will be fetched and displayed. We will use the Unsplash API to search for and retrieve the images. By the end of this tutorial, you will have a functional image search app with an infinite scroll feature.

Let us have a look at how the final application will look like:

ezgifcom-video-to-gif-(3)

image search app

Prerequisites:

Approach:

We’ll use Unsplash API to fetch images based on the user’s search query. We will include a debounced search input to delay the API request until the user pauses typing. We will also implement an infinite scroll by fetching more images when the user reaches the bottom of the page. A preloader spinner will be displayed while fetching images. The use of useState, useEffect, and useRef hooks will help us to manage the state and perform necessary actions.

 

Steps to Create React App:

Step 1: Create the project file using the command:

npx create-react-app <<Name_of_project>>

Step 2: Navigate to the folder using the command

cd <<Name_of_project>>

Step 3: Install the following packages

npm install unsplash-js lodash react-spinners

Modules:

  • unsplash-js: to interact with Unsplash this API.
  • lodash: to use debounce utility function.
  • react-spinners: to show spinner while fetching images.

The updated dependencies in package.json will look like this:

"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"react-spinners": "^0.13.8",
"unsplash-js": "^7.0.18",
"web-vitals": "^2.1.4"
}

Project Structure

It will look like the following.

Untitled

project structure

Note: Get your Unsplash API key from https://unsplash.com/

Example: Write the following code in respective files.

  • App.js: This file contains the main logic.
  • App.css: This file contains the styling.

Javascript




// App.js 
import "./App.css";
import { useState, useEffect, useRef } from "react";
import { createApi } from "unsplash-js";
import { debounce } from "lodash";
import { BounceLoader } from "react-spinners";
  
const unsplash = createApi({
    accessKey: << use your API Key>>,
});
  
function App() {
  
    // State variable to store the search phrase
    const [phrase, setPhrase] = useState("");
  
    // Ref to hold the current value of the search phrase
    const phraseRef = useRef(phrase);
  
    // State variable to store the fetched images
    const [images, setImages] = useState([]);
  
    // Ref to hold the current value of the fetched images
    const imagesRef = useRef(images);
  
    // State variable to indicate if images are being fetched
    const [fetching, setFetching] = useState(false);
  
    // Ref to hold the current value of the fetching state
    const fetchingRef = useRef(fetching);
  
    function getUnsplashImages(query, page = 1) {
        setFetching(true);
        fetchingRef.current = true;
        return new Promise((resolve, reject) => {
            unsplash.search
                .getPhotos({
                    query,
                    page,
                    perPage: 5,
                })
                .then((result) => {
                      
                    // Update fetching state to indicate 
                    //that images fetching is completed
                    setFetching(false);
                    fetchingRef.current = false;
                    resolve(result.response.results.map((result) =>
                        result.urls.regular));
                });
        });
    }
  
    useEffect(() => {
        phraseRef.current = phrase;
        if (phrase !== "")
            debounce(() => {
                setImages([]);
                getUnsplashImages(phrase, 1).then((images) => {
                    setImages(images);
                });
                imagesRef.current = images;
            }, 1000)();
    }, [phrase]);
  
    function handleScroll(e) {
        const { scrollHeight, scrollTop, clientHeight } =
            e.target.scrollingElement;
        const isBottom = scrollHeight - scrollTop <= clientHeight;
        if (isBottom && !fetchingRef.current) {
            getUnsplashImages(
                phraseRef.current,
                imagesRef.current.length / 5 + 1
            ).then((newImages) => {
                imagesRef.current = [...imagesRef.current, ...newImages];
                setImages(imagesRef.current);
            });
        }
    }
    useEffect(() => {
        document.addEventListener("scroll", handleScroll, { passive: true });
        return () =>
            document.removeEventListener("scroll", handleScroll);
    }, []);
  
    return (
        <div>
            <input
                type="text"
                value={phrase}
                onChange={(e) => setPhrase(e.target.value)}
            />
            <br />
            {images.length > 0 && images.map((url) =>
                <img src={url} />)}
            <div>
                {fetching && (
                    <div style={{ textAlign: "center" }}>
                        <BounceLoader speedMultiplier={5}
                            color="#000000" />
                    </div>
                )}
            </div>
        </div>
    );
}
  
export default App;


CSS




/* App.css  */
img {
  max-width: 100%;
}


Steps to Run the Application

Step 1: Type the following command in the terminal of your project directory

npm start

Step 2: Type the following URL in your web browser.

http://localhost:3000/

Output:

ezgifcom-video-to-gif-(3)

image search app

Whether you’re preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape, neveropen Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we’ve already empowered, and we’re here to do the same for you. Don’t miss out – check it out now!

RELATED ARTICLES

Most Popular

Recent Comments