Project 91 of 100 - Build a Grocery List in React Native with <FlatList />
Tags: reactnative, react, javascript, typescript
Published: 2022-01-03 06:09:04

*Hey! I'm on a mission to make 100 React.js projects. Please follow my dev.to profile or my [twitter](https://www.twitter.com/jwhubert91) for updates and feel free to reach out if you have questions. Thanks for your support!*

Link to the repo: [github](https://github.com/jwhubert91/project-91-reactNativeFlatList)

To begin part 2 on a short series on React Native, I thought I would explore some simple primitive components and generate a shopping list, which is a common first project in any new language or framework.

###Setting Up
This part will be a slight recap of [yesterday's project](https://dev.to/jwhubert91/project-90-of-100-react-native-starter-19g0), which you should read first to understand what's happening. Before writing any code, you'll need to set up the React Native project on your machine. To do this I recommend Expo. You can read about that process in my post from yesterday or take it directly from the React Native docs [link here](https://reactnative.dev/docs/environment-setup).

First, with the Expo CLI tools installed, I type `expo init ReactNativeList` into my command line (Terminal on Mac). This will show a few options that we can select from to generate a boilerplate React Native template that's preconfigured to be served with Expo. We definitely want to choose a Managed option, because those have the built steps already set up for us. I chose Typescript but it doesn't matter much for this small application.

![Expo CLI project type options](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mv4wmfi7dsdj76lj45r7.png)

With that generated, we should then navigate into the folder and then run either `npm start` or `yarn start` to serve the application with Expo. When this is successful it should show a QR code and a few other details about what's running on your computer.

![Expo developer tools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ffdrpkj2xi1rqzk0qz6z.png)
 
If you copy the URL that the developer tools are running on and paste that into your browser, you'll have access to the Expo Developer Tools, a very handy little GUI that shows a console for your application and a few options for which device you'd like to launch on. If you want to, at this point you could run the application on your phone by just scanning the QR code here with the Expo Go app installed on your device. But I did that yesterday, so today I chose the simulator.

###Building A List
So now if you open up your project folder in a code editor, you'll see the directory and a file called 'App' with either a `.js` or `.tsx` extension depending on whether or not you chose vanilla JS or Typescript. I need practice with Typescript so I chose TS.

The code editor should look something like this with the file `App` open:

![Code editor open to project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u1bmx49ki513175okl7m.png)

If you're familiar with React then you'll know about components in general. One major difference in React Native is that the components you write will have to be compiled and then run on multiple devices, so rather than writing everything for the web, the `react-native` package comes with a number of [core components](https://reactnative.dev/docs/components-and-apis#basic-components) that we can use easily across devices. Today we'll use the `FlatList` component.

To import FlatList, simply include it in the import statement in `App` like so:

```JS
import { StyleSheet, Text, View, FlatList } from 'react-native';
```

Next, we'll need some data to actually render in the list, so I created an array of objects which have `name` and `quantity` properties that I've typed as strings. Again, this is in Typescript:

```JS
  const groceries: {
    name: string;
    quantity: string;
  }[] = [
    {name: 'Broccoli', quantity: '8oz'},
    {name: 'Pasta', quantity: '12oz'},
    {name: 'Crushed Tomatoes', quantity: '22oz'},
    {name: 'Basil', quantity: '4oz'},
    {name: 'Garlic', quantity: '3oz'},
    {name: 'Baguette', quantity: '1 Large'},
  ];
```

###FlatList Required Props
Next, let's write a new `<FlatList />` component into our JSX. This React Native component takes a few required props for it to work. First, we need to give it the `data` prop to tell the list what our data source is, in our case it's our object `groceries`.

Then, we need to use the `renderItem` prop to tell the component what JSX we want it to render for each list item. I know this is a bit confusing if you're used to plain React. Remember, we need this to compile into multiple languages on multiple devices, so we're trying to tell React Native how to do that. The prop you pass in should be a JSX component and it assumes you are iterating over the array passed into the `data` prop so you can pass a variable representing a single list item in as an argument, which I simply call `item` here. I'm going render a simple <Text> item with `item.name` and `item.quantity` as strings inside, and voila... here's what that prop should look like now:

```JS
renderItem={({item}) => {
  return <Text style={ styles.listItem }>{ item.name } - Quantity: { item.quantity }</Text>
}}
```

The last prop we need to pass to our `ListItem` component is called `keyExtractor`. Essentially, this assures each item in the array has a unique JSX element assigned to it. We could get around this by making sure there is a `key` property with unique values on each item in our `groceries` array, but that would be unlikely to happen if we were using a real data source. I'm going to use the name.

At this point our JSX should look something like this:

```JS
  return (
    <View style={styles.container}>
      <View style={ styles.headerSafe }></View>
      <Text style={styles.headerText}>My React Native Grocery List</Text>
      <FlatList
        data={ groceries }
        keyExtractor={ grocery => grocery.name }
        renderItem={({item}) => {
          return <Text style={ styles.listItem }>{ item.name } - Quantity: { item.quantity }</Text>
        }}
      />
    </View>
  );
```

As you can see I've thrown in some styling into the `style` props for my JSX elements. This is totally optional. I'll skip over that since styling elements is outside the scope of this article but it's just standard inline React styling with CSS in JS.

(Aside: You may notice I have a `View` component with nothing inside it as the first child of our main container View element. This was just a hacky workaround to make sure the other elements are shown below the hardware of an iPhone. Don't worry about it.)

###Rendering our App
In the Expo Developer Tools, if you ran the app on your phone or if you chose to run it on a simulator, you should now have a list built in React Native. Good job!

![The final product shown on an iPhone 13](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/weabjeipkn6o95m23wg3.png)

**If you like projects like this and want to stay up to date with more, check out my Twitter [@jwhubert91](https://twitter.com/jwhubert91), I follow back! See you tomorrow for another project.**