The right way to use Flatlist + TypeScript + Styled Components in React Native
Tags: reactnative, typescript, styledcomponent
Published: 2022-02-21 13:58:56

## 1. Scenario
Let’s imagine that you need to implement a list of names using TypeScript + Styled Components, like the image below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i0xt2jm7a10c32zb8fcy.png)

## 2. Dependencies
If you haven’t installed styled-components yet, open your terminal inside your typescript React Native project, copy and paste the lines below:
```bash
yarn add styled-components
yarn add @types/styled-components -D
```

## 3. Implementing without Styled Components
I am going to implement the list without styled-components, so we can change one part per time.
First, I will define the interface of the objects that are going to be in the list and the data of the items that are going to be rendered

```typescript

export interface IUser {
  id: string;
  name: string;
}

const DATA = [
  {
    id: '1',
    name: 'Michael Scott',
  },
  {
    id: '2',
    name: 'Jim Halpert',
  },
  {
    id: '3',
    name: 'Pam Beesly',
  },
  {
    id: '4',
    name: 'Dwight Schrute',
  },
  {
    id: '5',
    name: 'Andy Bernard',
  },
  {
    id: '6',
    name: 'Ryan Howard',
  },
  {
    id: '7',
    name: 'Kelly Kapoor',
  },
  {
    id: '8',
    name: 'Toby Flenderson',
  },
  {
    id: '9',
    name: 'Stanley Hudson',
  },
  {
    id: '10',
    name: 'Phyllis Vance',
  },
];
```

Now I’m going to create the Component that will render each IUser item on the list.

```typescript
const Item = ({data}: {data: IUser}) => (
  <View
    style={{
      backgroundColor: '#eeeeee',
      borderRadius: 10,
      padding: 20,
      marginVertical: 8,
      marginHorizontal: 16,
    }}>
    <Text style={{fontSize: 24}}>{data.name}</Text>
  </View>
);
```

The first important part here is that you should destruct the data prop that we’re passing to the Item component and type it with the IUser interface.

Finally, I will create the Flatlist component:
```typescript
const App = () => {
  return (
    <View style={{flex: 1}}>
      <FlatList
        data={DATA}
        renderItem={({item}) => <Item data={item} />}
        keyExtractor={(item: IUser) => item.id}
      />
    </View>
  );
};
```
## 4. Adding Styled Components
Now, we are ready to refactor these components using styled-components.

First, I will create a file and name it styles.ts

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbzygluq5jaja8icaaid.png)

Now, I will create a style for each component that we created previously.

```typescript
import {FlatList} from 'react-native';
import styled from 'styled-components/native';
import {IUser} from './App';

export const Container = styled.View`
  flex: 1;
`;

export const ItemContainer = styled.View`
  background-color: #eeeeee;
  border-radius: 10px;
  padding: 20px;
  margin-vertical: 8px;
  margin-horizontal: 16px;
`;

export const ItemName = styled.Text`
  font-size: 24px;
`;

export const UsersList = styled.FlatList`
  padding: 20px;
`;
```

After that, we can replace the components with inline styles with the isolated styles that we just created.

```typescript

const Item = ({data}: {data: IUser}) => (
  <ItemContainer>
    <ItemName>{data.name}</ItemName>
  </ItemContainer>
);

const App = () => {
  const renderItem: ListRenderItem<IUser> = ({item}) => <Item data={item} />;

  return (
    <Container>
      <UsersList
        data={DATA}
        renderItem={renderItem}
        keyExtractor={(item: IUser) => item.id}
      />
    </Container>
  );
};
```

But you will see that Typescript will fire an error in your styled-Component created Flatlist

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sysu5ey4hnz4zjurttm3.png)

That’s because you have to declare the type of data that we’re passing to the Flatlist to the styled-component flatlist.

So go to your styles.ts file and change the UsersList style from:

```typescript
export const UsersList = styled.FlatList`
  padding: 20px;
`;
```
To:

```typescript
export const UsersList = styled(FlatList as new () => FlatList<IUser>)`
  padding: 20px;
`;
```

## 5. Conclusion and Final Result
Using TypeScript + Flatlists + Styled Components can be tricky sometimes, but I hope that this tutorial helps you somehow.

That’s our final App.tsx file:
```typescript
import React from 'react';
import {ListRenderItem} from 'react-native';
import {Container, ItemContainer, ItemName, UsersList} from './styles';

export interface IUser {
  id: string;
  name: string;
}

const DATA = [
  {
    id: '1',
    name: 'Michael Scott',
  },
  {
    id: '2',
    name: 'Jim Halpert',
  },
  {
    id: '3',
    name: 'Pam Beesly',
  },
  {
    id: '4',
    name: 'Dwight Schrute',
  },
  {
    id: '5',
    name: 'Andy Bernard',
  },
  {
    id: '6',
    name: 'Ryan Howard',
  },
  {
    id: '7',
    name: 'Kelly Kapoor',
  },
  {
    id: '8',
    name: 'Toby Flenderson',
  },
  {
    id: '9',
    name: 'Stanley Hudson',
  },
  {
    id: '10',
    name: 'Phyllis Vance',
  },
];

const Item = ({data}: {data: IUser}) => (
  <ItemContainer>
    <ItemName>{data.name}</ItemName>
  </ItemContainer>
);

const App = () => {
  const renderItem: ListRenderItem<IUser> = ({item}) => <Item data={item} />;

  return (
    <Container>
      <UsersList
        data={DATA}
        renderItem={renderItem}
        keyExtractor={(item: IUser) => item.id}
      />
    </Container>
  );
};

export default App;
```

And that’s our final styles.ts file:

```typescript
import {FlatList} from 'react-native';
import styled from 'styled-components/native';
import {IUser} from './App';

export const Container = styled.SafeAreaView`
  flex: 1;
`;

export const ItemContainer = styled.View`
  background-color: #eeeeee;
  border-radius: 10px;
  padding: 20px;
  margin-vertical: 8px;
  margin-horizontal: 16px;
`;

export const ItemName = styled.Text`
  font-size: 24px;
`;

export const UsersList = styled(FlatList as new () => FlatList<IUser>)`
  padding: 20px;
`;
```

And here’s the tutorial repository on [GitHub](https://github.com/juniorklawa/flatlist_example).