Crafting a Professional-Looking Carousel with React and MUI

Ltomblock
8 min readSep 30, 2023

Part 1

Very basic static example, using MUI’s preexisting card component

The Quest for a Professional Web App

When I embarked on building my first significant application, one thing was clear: aesthetics and user experience mattered immensely. A sleek, responsive design wasn’t just a luxury — it was a necessity. I sought to emulate the elegance and functionality of platforms I admire: Airbnb, Netflix, Apple TV, to name a few. Their user interfaces frequently employ two tools: “carousels” and “cards”. These design elements aren’t mere decoration; they’re fundamental components used to display information efficiently, attractively, and responsively.

Why React and MUI?

React was a natural choice for me. Its component-based architecture allows for building modular, scalable, and maintainable applications. The virtual DOM ensures optimized and efficient updates, making it a fantastic choice for dynamic user interfaces.

Material-UI, or MUI, on the other hand, is a popular library offering a collection of React components that implement Google’s Material Design. It promises to expedite the styling process, ensuring apps look contemporary and feel interactive.

The Unexpected Challenge

To my astonishment, when I rummaged through MUI’s extensive component library, there was no pre-existing ‘carousel’ component. This was both a surprise and a challenge. A carousel — such a ubiquitous element in modern web design — was something I assumed would be readily available. I also couldn't find any sort of tutorial or third party component that used MUI’s API’s.

However, as developers, challenges like this aren’t really setbacks; they’re opportunities. It was time to build my own.

Embarking on a Carousel Creation Journey

This tutorial is the first part of a series where I’ll walk you through crafting a carousel component using React and MUI. In this installment, we’re going to start simple. We’ll utilize a static card taken directly from MUI’s “card” component demo. Rather than using a dynamic or database-driven approach, we’re going to create an array of these cards and implement a carousel feature to display them seamlessly.

Before delving deep into the nuances of our carousel, let’s clarify what you’ll need:

Prerequisites:

  • A basic understanding of React.
  • Familiarity with MUI.
  • Cloning the repository from https://github.com/tweezerchef/carousel. This repo contains all the files, and by cloning it, you’ll have everything you need to follow along.

For those familiar with Node.js, React, and npm, the only extra installation required is for the necessary MUI libraries. This ensures that the styling and component structure is consistent with Material Design principles.

With the stage set, let’s embark on this development journey together. We’re about to transform a challenge into an opportunity, and by the end, you’ll possess the knowledge to create an elegant carousel component, reminiscent of those seen on the industry’s leading platforms.

Deployed Version Below

http://3.128.189.242:3000/

Unpacking the Carousel Component

1. Imports: Setting the Stage

What’s happening here?

  • React, useState, useEffect: These are fundamental hooks from React. useState lets us maintain state in our component, and useEffect allows us to run side-effects (like fetching data or updating the DOM).
  • Box, IconButton, Slide, Stack: These are components provided by MUI. The Box is a versatile component for styling. IconButton is a button that takes an icon as its child. Slide is an animation component. Stack is used for stacking children components.
  • NavigateBeforeIcon & NavigateNextIcon: These are icons from MUI that symbolize backward and forward navigation.
  • Card: This is the card component we’re importing, It is what will populate the carousel

2. Setting up our Component’s State

Breaking it down:

  • cards: An array that will store the cards to be displayed in the carousel.
  • currentPage: A number indicating the current page or set of cards displayed.
  • slideDirection: A string value that determines the slide animation direction, either “left” or “right.”

3. Configuring our Carousel’s Behavior

  • cardsPerPage: This constant defines how many cards to show per page.
  • duplicateCards: Creates an array of 10 duplicated cards using the Card component. This is a dummy set for demonstration.

4. Functions to Navigate the Carousel

  • handleNextPage & handlePrevPage: These are the functions called when the next or previous buttons are pressed. They update the current page and slide direction accordingly.

5. useEffect: Setting Initial Data

Here, we’re using the useEffect hook to initially set our cards to the duplicateCards array when the component mounts. The empty array [] means this effect runs only once, similar to componentDidMount in class components. When creating a more dynamic site, which we will cover in another tutorial, this would most be linked to some sort of call to collect the relevant data and then set the state of the “cards” array.

Moving on, we will continue past and into the “return” part of the component, where the rendering happens.

Rendering the Carousel

1. Container for the Carousel:

  • This is the outermost box or container for the carousel. It will house everything related to our carousel, including the navigation buttons and the cards.
  • Understanding the styles:
  • display: "flex": Initializes this container as a flexbox container. Flexbox is a CSS layout method designed to distribute space along a single column or row, even when the sizes of items are unknown.
  • flexDirection: "row": This makes the main axis horizontal, so the children (items inside this container) are laid out in rows.
  • alignItems: "center" & alignContent: "center": These ensure the items (like the cards and buttons) are centered vertically.
  • justifyContent: "center": This centers the items horizontally.
  • height: "400px": Sets a fixed height for the container.

2. Previous Page Button:

  • This is a button designed to move to the previous page or set of cards in our carousel.
  • onClick={handlePrevPage}: Executes the function handlePrevPage when the button is clicked. This function is responsible for updating the currentPage state to the previous page.
  • disabled={currentPage === 0}: This is a condition that disables the button when the current page is the first page (0). This prevents users from navigating to a non-existent previous page.
  • <NavigateBeforeIcon />: This is the icon that visually represents "go back" or "previous". It comes from the MUI library.

3. Container for Cards and Animation:

This box acts as a container for the cards. It ensures that the space designated for the cards always occupies the full width and height of the parent container.

4. Rendering Each Card:

Using the .map function, we iterate over each card in our cards state. For each card, we want to decide whether to display it based on the current page.

5. Display Logic for Cards:

  • The above box is wrapped around each card or set of cards.
  • key={card-${index}}: Provides a unique identifier for each card, which is important for React's reconciliation process.
  • The styling using display: currentPage === index ? "block" : "none" is crucial. It ensures that only the cards for the current page are displayed, while the rest are hidden.

6. Slide Animation for Cards:

  • This is the MUI Slide component that provides a sliding animation.
  • direction={slideDirection}: Specifies the direction of the slide based on the slideDirection state.
  • in={currentPage === index}: This prop determines if the content (i.e., the card) should enter the screen. If true, the card will slide in.

7. Stacking and Displaying a Subset of Cards:

  • Stack is an MUI component for stacking items. Here, we're using it to stack a subset of cards horizontally.
  • The cards.slice(...) function is crucial. It ensures we're only grabbing and displaying the subset of cards for the current page. It calculates which cards to display based on the current page (index) and the predefined number of cards per page (cardsPerPage).

8. Next Page Button:

  • This button is designed to move to the next page or set of cards.
  • The disabled logic here is a bit more complex than the previous button. It calculates if we’re on the last page of cards and, if so, disables the button to prevent navigating further.

That concludes this part of the coding tutorial, next we will briefly look into how to customize this code for your needs, and whats next

Customizing Your Carousel

When it comes to customizing this Carousel, there are several things you could do to make it suit your specific needs or give it a unique touch:

  1. Number of Cards Displayed:
  2. Currently, the number of cards displayed per page is set via the cardsPerPage constant. You can easily adjust this number to display more or fewer cards on each slide.
  3. Styling & Themes: Utilize Material-UI’s theming capabilities to change the appearance of the Carousel. This might include changing the colors, fonts, and size of cards.
  4. Card Content: The content of the card (<Card /> component) can be enriched. Instead of the dummy content provided, you could include images, text, links, or any other content you'd like to present.
  5. Navigation Icons: While the current implementation uses NavigateBeforeIcon and NavigateNextIcon for navigation, Material-UI provides a wide array of icons. Feel free to replace these with any icons that fit your aesthetic or usability goals.
  6. Animation & Transitions: The Slide component from Material-UI offers simple sliding animations. However, you could explore other animations like fade, zoom, or even custom animations to make the Carousel transitions more engaging.
  7. Dynamic Data Loading: In the given code, the cards are duplicated for demonstration purposes using the duplicateCards array. In a real-world scenario, you might want to load data dynamically, maybe from an API or database. This would replace the static data initialization.

Conclusion

The Carousel component you’ve walked through is a foundational example of how React and Material-UI can be used together to create interactive UI components. While this demo provides a basic implementation, the beauty of React and Material-UI lies in their flexibility and scalability.

In subsequent demos, we’ll delve deeper into adding more dynamic elements to our Carousel. Specifically, our next demo will focus on drawing information displayed on the cards from a remote PostgreSQL database, offering a more realistic use-case scenario. As we advance, you’ll see how seamlessly React integrates with various back-end systems and how components can be enriched with real-time data.

Whether you’re building a portfolio showcase, an e-commerce product slider, or any other content display, this Carousel serves as a versatile starting point. As always, the key lies in understanding the core concepts and then iterating upon them to suit your specific requirements. Happy coding!

--

--