Samaila Bala I'm a frontend engineer and technical writer.

Using React Native to implement a carousel

4 min read 1207

Implementing a Carousel With React Native

If you’ve ever wondered how to best use horizontal spaces on mobile applications, you should consider using carousels. Carousels help users cycle through series of content that can be displayed both horizontally and vertically, making it easy for developers to display content on various types of devices, especially mobile ones.

In this tutorial, we’ll create a carousel in a mobile application using React Native.

Prerequisites

We will be creating a carousel with a Tinder animation, but, before we begin, this tutorial assumes you have the following prerequisites:

  • Knowledge of JavaScript (ES6+)
  • Familiarity with React v16+
  • Knowledge of React Native
  • A code editor
  • Basic knowledge of a terminal
  • npm and/or yarn
  • Node.js (v10+)

Getting started

First, we’ll bootstrap our application with Expo. Open your terminal and type the code below to install the Expo CLI if you don’t have it installed already:

npm install expo-cli --global

After installing Expo, we can use it to initialize React Native. Navigate to a directory that you want to add your project to and type the following:

expo init ReactNativeCarouselTutorial

Choose a blank template in the managed workflow section.

Blank Template Example

After it’s installed all the necessary dependencies, navigate to the project directory in your terminal and start your project:

expo start

This launches Metro Bundler in your browser, giving you the option of running the application on your chosen emulator. You should be presented with a screenshot similar to the one below:

Metro Bundler Opened in Browser

We made a custom demo for .
No really. Click here to check it out.

Creating the carousel

To create a carousel, open your terminal, navigate to the project directory, and type this command:

npm install --save react-native-snap-carousel

This installs react-native-snap-carousel, which is a package we’ll use to create the carousel.

After installation, create a data.js file in your root directory and paste the code below:

export default data = [
  {
    title: "Aenean leo",
    body: "Ut tincidunt tincidunt erat. Sed cursus turpis vitae tortor. Quisque malesuada placerat nisl. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.",
    imgUrl: "https://picsum.photos/id/11/200/300"
  },
  {
    title: "In turpis",
    body: "Aenean ut eros et nisl sagittis vestibulum. Donec posuere vulputate arcu. Proin faucibus arcu quis ante. Curabitur at lacus ac velit ornare lobortis. ",
    imgUrl: "https://picsum.photos/id/10/200/300"
  },
  {
    title: "Lorem Ipsum",
    body: "Phasellus ullamcorper ipsum rutrum nunc. Nullam quis ante. Etiam ultricies nisi vel augue. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc.",
    imgUrl: "https://picsum.photos/id/12/200/300"
  }
]

The data file is an array that contains mock data that we will use to populate our carousel.

Next, create a file called CarouselCardItem.js and open it. Insert the following code:

import React from 'react'
import { View, Text, StyleSheet, Dimensions, Image } from "react-native"

export const SLIDER_WIDTH = Dimensions.get('window').width + 80
export const ITEM_WIDTH = Math.round(SLIDER_WIDTH * 0.7)

const CarouselCardItem = ({ item, index }) => {
  return (
    <View style={styles.container} key={index}>
      <Image
        source={{ uri: item.imgUrl }}
        style={styles.image}
      />
      <Text style={styles.header}>{item.title}</Text>
      <Text style={styles.body}>{item.body}</Text>
    </View>
  )
}
const styles = StyleSheet.create({
  container: {
    backgroundColor: 'white',
    borderRadius: 8,
    width: ITEM_WIDTH,
    paddingBottom: 40,
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 3,
    },
    shadowOpacity: 0.29,
    shadowRadius: 4.65,
    elevation: 7,
  },
  image: {
    width: ITEM_WIDTH,
    height: 300,
  },
  header: {
    color: "#222",
    fontSize: 28,
    fontWeight: "bold",
    paddingLeft: 20,
    paddingTop: 20
  },
  body: {
    color: "#222",
    fontSize: 18,
    paddingLeft: 20,
    paddingLeft: 20,
    paddingRight: 20
  }
})

export default CarouselCardItem

The CarouselCardItem implements the look of the cards in the carousel. It returns a component that will display the item passed as props.

Now, let’s create a component that will be responsible for displaying the carousel. Create a file called CarouselCards, open it, and enter the following code:

import React from 'react'
import { View } from "react-native"
import Carousel from 'react-native-snap-carousel'
import CarouselCardItem, { SLIDER_WIDTH, ITEM_WIDTH } from './CarouselCardItem'
import data from './data'

const CarouselCards = () => {
  const isCarousel = React.useRef(null)

  return (
    <View>
      <Carousel
        layout="tinder"
        layoutCardOffset={9}
        ref={isCarousel}
        data={data}
        renderItem={CarouselCardItem}
        sliderWidth={SLIDER_WIDTH}
        itemWidth={ITEM_WIDTH}
        inactiveSlideShift={0}
        useScrollView={true}
      />
    </View>
  )
}


export default CarouselCards

We use the Carousel component from the react-native-snap-carousel package to implement the carousel. The props accepted by the component include:

  • layout: it defines the way the items are rendered. The options include default, stack, and Tinder
  • layoutCardOffset: it is used to increase or decrease the default card offset in both the stack and Tinder layouts
  • ref: creates a reference to an instance of the carousel
  • data: array of items to loop on
  • renderItem: takes an item from the data and renders it into the list
  • sliderWidth: width in pixel of the carousel
  • itemWidth: width in pixel of the carousel item
  • useScrollView: choose to use a ScrollView component as opposed to a Flatlist component for performance reasons
  • onSnapToItem: snaps to a carousel item programmatically

Adding pagination

We can add pagination so users can skip to a certain item in the carousel without having to swipe continuously. The first thing we have to do is import the component. To do this, go to the line where we imported the carousel component:

import Carousel from 'react-native-snap-carousel'

And refactor it to look like this:

import Carousel, { Pagination } from 'react-native-snap-carousel'

Next, create a state to store the current pagination index:

const [index, setIndex] = React.useState(0)

After that, paste the following code below the carousel component:

<Pagination
  dotsLength={data.length}
  activeDotIndex={index}
  carouselRef={isCarousel}
  dotStyle={{
    width: 10,
    height: 10,
    borderRadius: 5,
    marginHorizontal: 0,
    backgroundColor: 'rgba(0, 0, 0, 0.92)'
  }}
  inactiveDotOpacity={0.4}
  inactiveDotScale={0.6}
  tappableDots={true}
/>

This renders the pagination component, which, by default, is a list of dots. The pagination component accepts the following props:

  • dotsLength: the number of dots to display
  • activeDotIndex: index of the current active dot
  • carouselRef: a reference to the carousel component, which the pagination is linked to
  • dotStyle: dots style to be merged with the default
  • inactiveDotOpacity: the value of opacity applied to inactive dots
  • inactiveDotScale: value of the scale transform applied to inactive dots
  • tappableDots: makes default dots tappable, so that when a dot is tapped, the carousel will slide to the corresponding item

The modified CarouselCards component should resemble the code below:

import React from 'react'
import { View } from "react-native"
import Carousel, { Pagination } from 'react-native-snap-carousel'
import CarouselCardItem, { SLIDER_WIDTH, ITEM_WIDTH } from './CarouselCardItem'
import data from './data'


const CarouselCards = () => {
  const [index, setIndex] = React.useState(0)
  const isCarousel = React.useRef(null)


  return (
    <View>
      <Carousel
        layout="tinder"
        layoutCardOffset={9}
        ref={isCarousel}
        data={data}
        renderItem={CarouselCardItem}
        sliderWidth={SLIDER_WIDTH}
        itemWidth={ITEM_WIDTH}
        onSnapToItem={(index) => setIndex(index)}
        useScrollView={true}
      />
      <Pagination
        dotsLength={data.length}
        activeDotIndex={index}
        carouselRef={isCarousel}
        dotStyle={{
          width: 10,
          height: 10,
          borderRadius: 5,
          marginHorizontal: 0,
          backgroundColor: 'rgba(0, 0, 0, 0.92)'
        }}
        inactiveDotOpacity={0.4}
        inactiveDotScale={0.6}
        tappableDots={true}
      />
    </View>

  )
}



export default CarouselCards

Now, go to your App.js file and refactor the code there to look like this:

import React from 'react'
import { SafeAreaView, StyleSheet } from 'react-native'
import CarouselCards from './CarouselCards'
export default function App() {
  return (
    <SafeAreaView style={styles.container}>
      <CarouselCards />
    </SafeAreaView>
  );
}
const styles = StyleSheet.create({
  container: {
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
    padding: 50
  },
});

After saving, you should be presented with a screenshot similar to this:

Successfully Implemented Carousel Screenshot

Congratulations! You’ve finished your carousel.

Conclusion

In this tutorial, we walked through implementing a carousel with React Native. We used react-native-snap-carousel, which provides many options for creating carousels. If you’d like to see a Snack showcase of this tutorial, check it out here.

: Full visibility into your web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.
Samaila Bala I'm a frontend engineer and technical writer.

4 Replies to “Using React Native to implement a carousel”

  1. Don’t forget to add this line to your Carousel component. I missed it too

    onSnapToItem={(index) => setIndex(index)}

    I hope it helps.

  2. Getting below error when I followed this

    TypeError: Cannot read property ‘style’ of undefined

Leave a Reply