Grid Columns in React Native: A Comprehensive Guide

Niraj Dhungana

Niraj Dhungana

4 Min Read

Published on: 24 Jul 2023

Share:
Grid Columns in React Native: A Comprehensive Guide

Mobile devices may be small, but as developers, we often find ourselves needing to go beyond their limitations to deliver exceptional user experiences. In this tutorial, we will push the boundaries of mobile design by harnessing the power of React Native's flex capabilities to create a robust and versatile grid view component.

Look how sophisticated I am sounding with this intro.

Now I don't want to waste your time by starting this post with how you can set up your react native project to have a grid view. I will directly jump into the GridView.


BTW this is how I initialize my project with typescript.

terminal
npx react-native init MyAwesomeProject --template react-native-template-typescript

Then you can simply open the project inside your IDE and then choose the file you want to work in. For me I have a new file called GridView.tsx

The very first thing that I will type here is rntsfc which will create a react native typescript functional component. Well how can I run this weird command to generate all these things for me and if you want to know more watch 👉 video.

My GirdView component for now looks like this.

GridView.tsx
import {FC} from 'react';
import {View, StyleSheet} from 'react-native';

interface Props {}

const GridView: FC<Props> = (props) => {
  return <View style={styles.container}></View>;
};

const styles = StyleSheet.create({
  container: {},
});

export default GridView;

Now it’s time to accept a few props for our GridView so that we can move to the next part. Those are going to be data, col and the renderItem function.

I am using typescript so first I am going to initialize an interface, if you are using javascript then you can skip this part.

GridView.tsx
import {FC} from 'react';
import {View, StyleSheet} from 'react-native';

interface Props<T> { 
  data: T[];
  renderItem(item: T): JSX.Element;
  col?: number;
}

const GridView ...

First let me explain what these props will do, data is the list of data that we want to render which will be an array of some types. Then we have a renderItem function which will help later to render items, with custom look and feel. It is the same as the renderItem function for FlatList.  Then col will be the number of columns that we want for our grid.

If you are confused about <T>. This is the generic type that I am accepting for data and renderItem so that later we can get the correct suggestion from Typescript. But for that we need to also pass this to the interface like below.

GridView.tsx
interface {
  ...
  
const GridView = <T extends any>(props: Props<T>) => {
  ...

Now let’s destructure all of the props and give a default value of 2 for grid col props. So that we can render 2 columns by default. Also use map method for data and use the renderItem method and pass the single item from data to it.

GridView.tsx
...
const GridView = <T extends any>(props: Props<T>) => {
  const {data, col = 2, renderItem} = props;
  return (
    <View style={styles.container}>
      {data.map((item, index) => {
        return (
          <View key={index} style={{width: 100 / col + '%'}}>
            <View style={{padding: 5}}>{renderItem(item)}</View>
          </View>
        );
      })}
    </View>
  );
};
...

Basically this code is explaining it on its own but let me give you some explanation if you need. Here we have the data that we want to render which will be an array and we are using map method on this data so that we can render all of the items from it.

But we don’t want to render them inside this component. We want to give flexibility to add any kind of component or style for these list items. So for that we are using the renderItem method.

Also if you notice I am using style for the view where we are rendering single items width / 100 * col + "%". Well this is just to assign the desired width percentages according to columns that we want and you will understand about it later.

Now you can also add some style for your container which will give us the grid view that we wanted so far.

GridView.tsx
...
const styles = StyleSheet.create({
  container: {width: '100%', flexDirection: 'row', flexWrap: 'wrap'},
});
...

Yes that flex wrap is the property which will render items to the next line if it overflows the container size. And because we have divided the width for our items equally with the formula width / 100 * col + "%". We are going to have the exact thing that we want. The GridView.

Now if we use it inside our App component like below or wherever you want to render your grid view.

App.tsx
const App = () => {
  const dummyData = [
    { name: "John Doe", id: 1 },
    { name: "Jemmy", id: 2 },
    { name: "Niraj", id: 3 },
    { name: "You", id: 4 },
  ];
  return (
    <View style={{ paddingTop: 40 }}>
      <GridView
        data={dummyData}
        renderItem={(item) => {
          return (
            <View style={styles.container}>
              <Text style={styles.title}>{item.name}</Text>
            </View>
          );
        }}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    height: 150,
    backgroundColor: "rgba(0, 0, 0, 0.5)",
    borderRadius: 5,
    marginBottom: 10,
    justifyContent: "center",
    alignItems: "center",
  },
  title: { color: "white", fontWeight: "bold", fontSize: 25 },
});

export default App;

You will get the grid view.

something was there

Also because of the generic type <T> that we used earlier. We have the correct type suggestion.

something was there

Here are some screenshots of the project where we are using this same component. You can check out the complete full stack react native course here.