Creating a Responsive Image Gallery in React: A Step-by-Step Guide
Table of contents
Building a responsive scroll gallery in React can be quite complicated but it’s a very valuable feature to add to a lot of projects requiring a gallery of sorts. But don’t worry, in this blog post, I shall guide you through the process step-by-step.
Prerequisites:
Must have installed npm and created a React application.
Must have cleared all default styles and app.js contents.
Step 1: Create the imageData.js file, Import the images and sort them into an array of objects
To build a gallery component, you’ll need images. Create an imageData.js file where you can import images from the assets folder and organize them in an array of objects. This array will help you display images based on their assigned data (e.g., id, category, imageUrl).
Step 2: Create the Gallery component
This component will render all the images from the selected array that will be passed as a prop to the component. We will be using a map method on the array to render every image in it with a unique key which would be the id of the image.
import React from "react";
const Gallery = ({ images }) => {
return (
<div className="gallery">
{images.map((image) => (
<img key={image.id} src={image.imageUrl} alt={`Img ${image.id}`} />
))}
</div>
);
};
export default Gallery;
import React from “react”;
const Gallery = ({ images }) => {
return (
<div className=”gallery”>
{images.map((image) => (
<img key={image.id} src={image.imageUrl} alt={`Img ${image.id}`} />
))}
</div>
);
};
export default Gallery;
Step 3: Create the CategoryMenu component
The CategoryMenu component serves as a navigation bar with image categories. It renders images matching the selected category when clicked. It accepts three props: categories (defining available categories), activeCategory (for styling the active category), and onSelectCategory (to display images for a selected category). To make it responsive, we’ll use useRef and useEffect hooks for scrolling.
import React, { useRef, useEffect } from "react";
import './styles.css';
const CategoryMenu = ({ categories, activeCategory, onSelectCategory }) => {
const submenuRef = useRef(null);
const handleScroll = () => {
if (submenuRef.current) {
const submenuWidth = submenuRef.current.clientWidth;
const submenuScrollWidth = submenuRef.current.scrollWidth;
if (submenuScrollWidth > submenuWidth) {
submenuRef.current.scrollRight = submenuScrollWidth + submenuWidth;
}
else {
submenuRef.current.scrollRight = 0;
}
}
};
useEffect(() => {
handleScroll();
}, []);
return (
<div className="submenu-wrapper">
<div className="submenu" ref={submenuRef} id="id">
{categories.map((category, index) => (
<button
key={category}
onClick={() => onSelectCategory(category, index)}
className={`${category === activeCategory ? "active" : ""} ${
index > categories.indexOf(activeCategory) ? "category-at-right" : "category-at-left"
}`}
>
{category}
</button>
))}
</div>
</div>
);
};
export default CategoryMenu;
Step 4: Writing the App.js component
In the App.js file, import the Gallery and CategoryMenu components, as well as the imageData.js file. Create an array of unique categories and manage the active category using useState. Define a function to handle category selection and filter images accordingly. Render the components within a container.
To explain in-depth, we’llfilter the imageData array to get only the images that belong to the activeCategory. The component renders a div container that wraps the CategoryMenu and Gallery components. The CategoryMenu component is rendered with the categories, activeCategory, and handleSelectCategory props. The Gallery component is rendered with the filteredImages prop.
import React, { useState } from "react";
import MainGallery from "../GalleryPage/MainGallery";
import CategoryMenu from "../GalleryPage/CategoryMenu";
import imageData from "../imageData";
function GalleryPage() {
const categories = […new Set(imageData.map((image) => image.category))];
const [activeCategory, setActiveCategory] = useState(categories[0]);
const handleSelectCategory = (category) => {
setActiveCategory(category);
};
const filteredImages = imageData.filter(
(image) => image.category === activeCategory
);
return (
<div>
<CategoryMenu
categories={categories}
activeCategory={activeCategory}
onSelectCategory={handleSelectCategory}
/>
<MainGallery images={filteredImages} />
</div>
)
};
export default GalleryPage;
Overall, this code sets up a gallery page with a category menu that allows users to filter the images being displayed in the main gallery based on selected categories.
Step 5: Apply styling to the CategoryMenu and Gallery components
Apply styling to the CategoryMenu and Gallery components as needed. Set overflow-x to enable horizontal scrolling when the category menu exceeds the container’s width. In the Gallery component, use grid layout and apply styles according to your project’s requirements.
And there you have it! A functional and responsive gallery that you can use for your projects, if you’re confused about how it works you can refer to a project where I built a gallery and also the GitHub repository.
Thanks for reading!
Subscribe to my newsletter
Read articles from Ifeanyi Aladi directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Ifeanyi Aladi
Ifeanyi Aladi
I'm Aladi Ifeanyi, a frontend developer in Lagos with a passion for creating engaging websites that blend design and functionality. My journey in web development began with a fascination for technology, and I've since honed my skills in crafting modern and user-friendly interfaces. I'm a firm believer in open-source collaboration and the power of sharing knowledge. Let's connect and work together to make the web a better place! Get in touch and let's chat about all things web and beyond.