Build an Image Search App with Infinite Scroll using React JS
Last Updated :
29 Jul, 2024
This article delves into building a React-based image search app with infinite scroll. Users can search for images based on a query, and as they scroll down, additional images are fetched and shown. The Unsplash API is employed for searching and retrieving these images, resulting in a fully operational image search app with an integrated infinite scroll feature by the end of the tutorial.
Prerequisites:
Approach to create Image Search App:
Utilizing the Unsplash API, we'll retrieve images according to the user's search input. Implementing a debounced search input ensures delayed API requests during typing pauses. Additionally, an infinite scroll feature loads more images as the user reaches the page's bottom, accompanied by a preloader spinner. The state management and required actions are facilitated through the useState, useEffect, and useRef hooks.
Steps to Create React App and Installing modules:
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.
Project Structure:
project structureThe updated dependencies in package.json file will look like:
"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"
}
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.
CSS
/* App.css */
img {
max-width: 100%;
}
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;
Steps to Run the Application:
Step 1:Â Type the following command in the terminal of your project directory
npm start
Output: Type the following URL in your web browser http://localhost:3000/
Similar Reads
Implementing Infinite Scrolling with React Hooks Infinite Scroll is a crucial aspect of many web applications, ensuring that users have access to infinite content while keeping the user experience in mind. In this article, weâll explore how to implement infinite scroll flows in a React application using React Hooks. Prerequisites:NPM and NodeReact
6 min read
Movie Search Engine Using React and API In this article, we will create Movie Search Engine using ReactJS. In this movie search engine the user can search for movies which they want to know about and the search engine will fetch a list of movies from that keyword and display the result in the forms of card. A default search has been loade
6 min read
Pagination and Infinite Scrolling with React Hooks In the world of web development, making long lists of items like posts, products, or comments easy to navigate is super important. Two common ways to do this are Pagination and Infinite Scrolling. In this guide, we'll walk through how to implement both of these techniques using React Hooks. Don't wo
4 min read
Implementing Pagination and Infinite Scrolling with React Hooks This article will discuss pagination and infinite scrolling. These concepts are commonly used in web applications to enhance the user experience. Pagination and infinite scrolling both help in the efficient handling of huge data sizes. Approach to Implement Pagination and Infinite Scrolling:Paginati
6 min read
How to Build a Search Filter using React Hooks ? In modern web development, implementing a search feature is a common requirement for various applications. With React Hooks, developers can efficiently manage state and lifecycle events, making it an ideal choice for building interactive user interfaces, including search functionalities. In this art
4 min read