Simple shimmer placeholder in React Native
Tags: reactnative, placeholder, javascript, typescript
Published: 2024-02-03 18:47:17

In this short tutorial I will show you how to create **a simple placeholder with a shimmering effect** for your React Native app.

## The libraries

We will be using two libraries: `react-native-linear-gradient` and `react-native-gradient-shimmer`.

Run these two commands to **install them**:
`yarn add react-native-linear-gradient@next
yarn add react-native-gradient-shimmer`
or, for npm:
`npm install react-native-linear-gradient@next
npm install react-native-gradient-shimmer`

> **Important!** Why do we use `@next`? There is an **open issue** with the current stable version (as of February 2024) of `react-native-linear-gradient` library that causes problems when trying to create a shimmer placeholder, so we are using the pre-release 3.0.0-alpha.1 version. You can check if the new stable version is available here: [Github page](https://github.com/react-native-linear-gradient/react-native-linear-gradient/releases)

## Creating the shimmer component
I suggest that you use the library to create a single **custom component** that you can use anywhere in your app.

An example of a component:

```typescript
import React, { FC } from 'react';
import LinearGradient from 'react-native-linear-gradient';
import GradientShimmer from 'react-native-gradient-shimmer';

interface PlaceholderWithShimmerProps {
  height?: number;
  width?: number;
  style?: any;
}

const PlaceholderWithShimmer: FC<PlaceholderWithShimmerProps> = React.memo(
  ({ height, width, style }) => {
    return (
      <GradientShimmer
        LinearGradientComponent={LinearGradient}
        backgroundColor={'gray'}
        highlightColor={'white'}
        height={height}
        width={width}
        style={style}
      />
);},);

export default PlaceholderWithShimmer;
```

> **Important!** The library component **requires** a specified `width` and `height` (as a number) to work correctly. Your placeholder may look a bit different from the component it's supposed to replace - that's not a problem as long as it serves its purpose of informing the user that the content is loading.

There is also room for **customisation**! There are a few additional props that can change the look of your placeholder:
`duration` - the time it takes for the animation to play;
`highlightWidth` - the width of the highlighted area.
You can also set your own colors changing the values of the `backgroundColor` and `highlightColor` props.

Now, you can use this component anywhere in your app by setting different `width`, `height` and `style`.

## Creating the placeholder

When creating a placeholder, the first thing I do is look at the styles of the original component that it is replacing and try to replicate the position of the elements.

Here I have a simple item card component:

![Original component image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zss1k6lykt7miyzdk30k.jpg)

I've used the same structure as the original component for my placeholder, replacing the `Text` and `Button` elements with the custom shimmering placeholder we created:

```typescript
const ProductCardSkeleton: FC = () => {
  return (
    <View style={cardStyles.cardContainer}>
      <View style={cardStyles.image} />

      <View style={cardStyles.bottomHalfContainer}>
        <PlaceholderWithShimmer style={cardStyles.productTitle} />
        <PlaceholderWithShimmer style={cardStyles.productTitle2} />
        <PlaceholderWithShimmer style={cardStyles.priceLabel} />
        <PlaceholderWithShimmer style={cardStyles.button} />
      </View>
    </View>
  );
};
```

> **Tip!** You can set up `width` and `height` of a component using `style`. Also, be careful not to make the components too big - they may not fit inside the parent component on smaller devices.

```typescript
productTitle: {
    height: 18,
    backgroundColor: 'gray',
    borderRadius: 12,
    marginBottom: 4,
    width: 120,
  }
```
This is what the placeholder looks like now (not an animated gif, sorry!):

![Placeholder start of the animation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nxk2pwl8e08fikwsrq09.png)


![Placeholder middle of the animation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ij06aldouan23s15cy3u.png)

> I recommend that you reload the application after changing the components, as not doing this can cause the shimmering animation to appear out of sync.

This is it! I hope this post was helpful! If there are better ways to create a shimmering effect component in React Native, I'd love to hear about it in the comments!

> You can also use the component **without specifying** the `width` and `height` (in case you need to size your shimmering elements using other methods, like `flex` or `alignSelf`), but this will cause errors when running the app and may lead to unexpected problems.