Building a React Native Filter - Part 1
Tags: javascript, webdev, beginners, react
Published: 2022-02-17 18:08:39


![App Walkthrough](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jxwau6dlwf85sch0wfpj.gif)

A couple of weeks ago a client asked us to create an application that displayed all of it's stores. The app had to be built in **React Native** in order to speed up development time and ensure compatibility among Android and IOS and had to include a full list of our client's stores. This list was fetched from a MongoDB collection, and came as an array of objects containing information for each store (such as location, phone number, email, coordinates). Obviously, a plain list of objects doesn't satisfy a customer, as scrolling through a 189 store list to find a specific one might be extremely painful. So with React Native (our choice to build fast compatible apps) we decided to create a filter. The filter we built included features such as **searching, categorizing and ordering according to proximity**. 

In this article, we will show you how the filter was built by using a <u>mock API</u> to build a filter with search and categorization (in the future we will write another article to show how to handle location based objects, order them and filter them). The tutorial will not cover a step by step of the whole code, but will go through the most important parts when building it. You can find the whole code in **this** [**Expo Snack**](https://snack.expo.dev/@rochi/react-native-filter). 

You will see this is a **front-end built filter**, and doesn't use backend filtering. Although backend filtering is a good option (particularly to handle long lists), it works smoothly with the data we have. **Bear in mind** if you have millions of elements mapping through them will impact negatively on the app's performance. 


![Main view of our application](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1j9ahi8xjcgi6h4vyd6.jpg)

So, to start we will be using [Fruityvice's API](https://www.fruityvice.com/) that will bring a response with an array of objects containing different information about fruits. An example for the response we get is:

```json 
[{
    "genus": "Malus",
    "name": "Apple",
    "id": 6,
    "family": "Rosaceae",
    "order": "Rosales",
    "nutritions": {
        "carbohydrates": 11.4,
        "protein": 0.3,
        "fat": 0.4,
        "calories": 52,
        "sugar": 10.3
    }
}, ...]
```

## Project Structure

Let's get hands on it to the real code. The structure our project will take is: 
1. A main App.js file where most of the work will happen, here we will set the main states and fetch our data. 
2. Components folder.
3. Assets folder.
4. Data folder in order to save the initial state some variables will have.

## Fetching the API

The first thing we should do, is fetch the API. We fetch it through a simple **fetch function built in a useEffect**, meaning each time the component mounts, the API is fetched and the fruits "refresh". The response is saved as a json and we can now work with it.

```js
  useEffect(() => {
    fetch('https://www.fruityvice.com/api/fruit/all')
      .then((response) => response.json())
      .then((json) => setFruits(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }, []);
```

## Our App.js Component

We create a `<SafeAreaView />` for our App.js (so that the content we build is contained within a visible space). Inside the SafeAreaView we will have three components, the **AppBar** (that will hold the modal and a logo for our app), the **modal** itself, and the **Wrapper** (called `<FruitsWrapper />`) where we will render the "card-styled" list of fruits with their information.

On the App.js we'll also do two things that will help us handle the Filtering correctly. 

First we'll set a couple of states:

```js
  const [fruits, setFruits] = useState([]);
  const [filter, setFilter] = useState(initialFilter);
  const [intermediateFilter, setIntermediateFilter] = useState(initialFilter)
   const [modalVisible, setModalVisible] = useState(false);
```

* _fruits_ holds the array of objects we fetch from the API
* _filter_ filter is the real filter that will be applied when the user decides to APPLY the filter within the modal
* _intermediateFilter_ is a filter that is setted while the user interacts with the modal, once the apply button is pressed, the intermediateFilter becomes the actual filter
* _modalVisible_ will handle modal visibility 

> **_Why the intermediateFilter?_** the intermediate filter ensures the fields the user clicks while in the modal will be applied correctly. We need to save the user choices as he/she advances through the modal.

Both the intermediateFilter and the filter take up an _**initialFilter**_. What is this? The `initialFilter` is a js written in our data folder. initialFilter is an object that hold's the initial state of the fields we are going to filter.

```js
export const initialFilter = {
  query: '',
  genus: '',
  carbohydrates: '', 
}
```

## The AppBar


![App Bar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5c4sy0vuoolxtg74j6j7.jpg)

The App bar is extremely simple. We have a logo, and a button that when pressed will change the state of the `modalVisible` variable to true and show us the modal. 

## Displaying the info


![sample of "Apple" card](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shfihowh8uwc2kkcevvn.jpg)

Before we filter we want to display multiple cards containing information about the fruits so we can then sort them according to the user's choices. For this we have two components `<FruitsWrapper />` and `<InfoCard/>`

* `<FruitsWrapper />` is the wrapper where we map through the fruits and display them. In this Wrapper we will also have the <u>filtering instance</u>. So as long as there no filters it will display the complete object we receive from the fetch. If there filters, we will push fruits to a new variable that will be empty. 

* `<InfoCard/>` is the UI of the card that will hold the object's info. We build only one object, and then map the fetch response and render each fruit (with it's information in the cards).

### The `<FruitsWrapper />`

This component is **SUPER** important. As the logic applied here makes the magic to display the filtered content. 

You can see that at the beginning of the component I declared two boolean variables: `filterFruits` and `empty` (empty will not be used yet, but will serve us to display that no fruits were fetched). I then set up an **empty filterArray** where the fruits I filter with my modal will be pushed. After doing this I set `filterFruits` equal to `allFruits`, the later one being the whole fruit array we brought on the first place. The following logic is key to filtering:

```js
if (filterFruits != undefined && && typeof filterFruits === 'object'){
    filterFruits.map((fruit) => {
    // I have two things, the filter and the fruits genus (in the array) so if I filter I only want to show the ones that match the genus
    if (filter.genus != '' && !fruit.genus.includes(filter.genus)) {
      return
    }

    filterArray.push(fruit)

  })
        if (filterArray.length > 0) {
        filterFruits = filterArray;
      }
} else {
  filterFruits = false
  empty= true
}
```

The filtering happens if `filterFruits` (before known as allFruits) is **not undefined** (meaning it has some content) and the **type of this is an object**. What we do is map through each fruit, if it <u>doesn't match</u> the parameters we want it to, we **return**, else we **push it** to the `filterArray`. If the filter array is bigger than 0 (meaning fruits were pushed) `filterArray` (the one where we pushed) becomes `filterFruits`. 

## The Modal


![An image of the App's modal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lcqr48pwfdpktsco7kl5.jpg)

The modal is the most important part of this tutorial. For this we will use **React Native's built in modal**.

> In the application we built for the client we had two modal instances, the _filtering modal_ (that used the native modal) and an _alert modal_ (where we used [UI Kitten's](https://akveo.github.io/react-native-ui-kitten/) modal). We like the native modal because it offers us the possibility of deciding how it transitions and it's easier to set it up fullscreen. 

As we mentioned previously we chose to use an **intermediate filter within the modal** so that the state management can be smooth, and we can access the different states (Remember that the `initalFilter` was an object?). Yet, after the user click's the apply button, we want the `intermediateFilter` to become the actual `filter`

A key thing we also have in this modal is the list of all the genus. Instead of mapping all the fruits and displaying the genus, in the App.js we created an array with **all the unique genus** (so that we don't get them repeated). The following code creates an array of all the fruit.genus unique values:

```
const genusResult = allFruits.map(item => item.genus)
  .filter((value, index, self) => self.indexOf(value) === index)
```

We loop through this array that we built to create the radio buttons, as you will see in the `RadioButton.js` file. This file holds custom built Radio Buttons. The good thing about this is that they are fully customizable, and give us more control over the user selection. 

The thing is, the user can only select one genus, and when the user selects the genus selected is saved in the intermediate filter. Once the user decides which genus he/she wants to see, he applies the filter and because of the logic applied in the `<FruitsWrapper />` only the fruits that have that genus will be shown. 

## Closing Remarks

This was a quick tutorial over how to build the filter. We hope it was easy to follow and in the second part we will talk about querying filtering. 

Remember the full code is in our [Expo Snack](https://snack.expo.dev/@rochi/react-native-filter)