The right way to use Flatlist + TypeScript + Styled Components in React Native

juniorklawa

Everaldo Junior

Posted on February 21, 2022

The right way to use Flatlist + TypeScript + Styled Components in React Native

1. Scenario

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

Image description

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:



yarn add styled-components
yarn add @types/styled-components -D


Enter fullscreen mode Exit fullscreen mode

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




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',
  },
];


Enter fullscreen mode Exit fullscreen mode

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



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>
);


Enter fullscreen mode Exit fullscreen mode

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:



const App = () => {
  return (
    <View style={{flex: 1}}>
      <FlatList
        data={DATA}
        renderItem={({item}) => <Item data={item} />}
        keyExtractor={(item: IUser) => item.id}
      />
    </View>
  );
};


Enter fullscreen mode Exit fullscreen mode

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

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



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;
`;


Enter fullscreen mode Exit fullscreen mode

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




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>
  );
};


Enter fullscreen mode Exit fullscreen mode

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

Image description

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:



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


Enter fullscreen mode Exit fullscreen mode

To:



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


Enter fullscreen mode Exit fullscreen mode

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:



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;


Enter fullscreen mode Exit fullscreen mode

And that’s our final styles.ts file:



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;
`;


Enter fullscreen mode Exit fullscreen mode

And here’s the tutorial repository on GitHub.

💖 💪 🙅 🚩
juniorklawa
Everaldo Junior

Posted on February 21, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related