Expo + React Native Navigation
Tags: reactnative, tutorial
Published: 2020-10-31 17:44:35

#### Building lite handy Reddit client for iOS and Android using [Expo](https://docs.expo.io) and [React Native Navigation](https://wix.github.io/react-native-navigation/).

Hi guys!

I am going to walk you through the whole process of building a mobile app using [**React Native**](https://reactnative.dev/). It is going to be a simple one but I might be adding more features with time. But the most exciting thing about this app is that it is using [**Expo SDK**](https://docs.expo.io/) with [**React Native Navigation**](https://wix.github.io/react-native-navigation/) that gives you a powerful set of tools and truly native navigation. Instead of using the default solution ([**react-navigation**](https://reactnavigation.org/)) in Expo (which is great, honestly), I prefer RNN as I love the native feel (iOS & Android native). I have been using React Native Navigation for years (in total) building apps with React Native. I also contribute to RNN community by providing the most up-to-date boilerplate/starter for the time ([**old**](https://github.com/kanzitelli/react-native-navigation-mobx-boilerplate)). I have recently released a new version of a boilerplate/starter [**expo-rnn-starter**](https://github.com/kanzitelli/expo-rnn-starter) which includes pre-configured up-to-date versions of Expo SDK, React Native Navigation, Reanimated 2, MobX, Dark Mode support, Expo Updates. It has been *a not so fast* process due to some tricks with Expo SDK and React Native Navigation integration but this process was also pretty exciting: I couldn't find any related tutorial or information on how to do it. And yes, this starter is ready for production and was used to bootstrap some of my apps which are published in the App Store and Google Play. That’s why, in order to start up very fast with the [**Rabbit app**](https://rabbitapp.batyr.io/app), we will use [**expo-rnn-starter**](https://github.com/kanzitelli/expo-rnn-starter).

If you would like to try out the app, here are links for [**App Store**](https://apps.apple.com/us/app/rabbit-app-lite-reddit-client/id1535084154)  and [**Google Play**](https://play.google.com/store/apps/details?id=io.batyr.rabbitapp)  (direct  [**.apk file link**](https://rabbitapp.batyr.io/android_app.apk)).

If you would like to dig into the code, here is a link to the [**Github repo**](https://github.com/kanzitelli/rabbit-app). Also, it’s worth saying that it is not going to be a copy-paste tutorial but something like a *learn-by-doing* process and approach from an indie developer.

# Why?

There are two reasons:

1.  I use Reddit quite often and mostly for reading [**r/reactnative**](https://www.reddit.com/r/reactnative) thread. That’s why I have decided to create a lite handy app because the official app and other clients are too overwhelming for me, I love simplicity.
2.  A year ago I have been working on a [**side project**](https://medium.com/@kanzitelli/good-news-app-golang-flutter-hummingbird-1949f22b299f), trying out [**Flutter**](https://flutter.dev/), and getting some new knowledge in [**Golang**](https://golang.org/). So the app was kind of a news app but all content was parsed from actual websites. I wanted to try something new in Golang and did a [**good job**](https://github.com/kanzitelli/good-news-backend) for my self-progress by learning [**how to crawl sites and publishing a server on DigitalOcean behind Traefik proxy**](https://medium.com/@kanzitelli/good-news-app-backend-in-golang-behind-traefik-reverse-proxy-with-https-available-2165b11467e4). And as a framework for creating mobile apps, I have decided to pick Flutter. So here is the [**Github repo**](https://github.com/kanzitelli/good-news-flutter-release) but I have never published it or continued working on other parts of that tutorial because Flutter performance in **release** mode on iOS was pretty bad, not native feel at all. Maybe things have changed since then, I have never tried it again. And yes, this is the reason I have built the Rabbit app and would like to share the process with the community.

# Let’s start

The first thing we need to do is to bootstrap our new app from [**expo-rnn-starter**](https://github.com/kanzitelli/expo-rnn-starter):

Open the terminal and follow next steps:
```
~ cd <to-your-desired-folder>
~ git clone https://github.com/kanzitelli/expo-rnn-starter.git rabbitapp && cd rabbitapp
~ rm -rf .git # to remove starter's git history
~ yarn && yarn ios:pods # it might take some time
```

After the process is done, let’s rename our app because information such as bundle identifiers, etc. is from the starter. For this purpose, I recommend using [**react-native-rename-next**](https://github.com/mayconmesquita/react-native-rename-next), which is the most up-to-date version I could find. Now please open its Github repository and follow the installation steps. After you are done, you can rename the app (any name and bundle identifier):

```
~ react-native-rename-next "rabbitapp" -b io.batyr.rabbitapp
~ yarn ios:pods
```

As mentioned on the main page of the library, we need to change the bundle identifier for iOS in XCode in the General section.

Now you should be able to successfully launch an app:

```
~ yarn ios # or
~ yarn android # or yarn android:release - for release build
```

Now we start coding! Open the app’s folder in your favorite text editor (for example, VSCode which is really good!) and get ready for some fun time.

## App functionality & structure

Ooops…, I forgot to talk about app functionality and structure.

This is going to be a *very* alpha version with minimum functionality. Below you can find a list of main functionalities in the big picture as you would write them down briefly on a napkin:

1.  A screen with a list of subreddits. Add/Delete functionality.
2.  A screen with a list of posts of a subreddit.
3.  A screen with a post, open in a webview, for example. Save/Remove functionality.
4.  A screen with saved posts. Remove functionality (same as 3rd).
5.  Settings. Just simple actions as app rate, mail composer to write to support, etc.
6.  So it seems like a tab-based app would be a perfect fit for this structure with the following tabs: Subreddits, Saved, Settings.
7.  Very minimalistic, fast, and easy to use.

The main question here is how we are going to get the data. Basically, I use this pattern to get data from Reddit `https://www.reddit.com/r/${subreddit}.json`, for example, `https://www.reddit.com/r/reactnative.json`, which gives a `.json` object with all needed data (first 25 posts). Each post and response from Reddit has a specific structure that I have already identified and we will add all the types to `/utils/types.d.ts` once we start coding. As you are here, probably the app has already been launched and you can see what you get from the starter. So now it’s the right time to start coding!

# Coding

## Setting up navigation

So as was mentioned before, we are going to have a tab-based app with 3 tabs. Let’s create 3 screens which will be presented on each tab. In order to make it more convenient and faster for you, you could make 3 copies of `example-screen.tsx` file in `screens` folder and rename them to `SubredditsScreen.tsx` , `SavedScreen.tsx` and `SettingsScreen.tsx` , also change the names of components for each screen, like:

![Image for post](https://miro.medium.com/max/60/1*u4bUc_SYnlPoAfmCNO_F1g.png?q=20)

![Image for post](https://miro.medium.com/max/2792/1*u4bUc_SYnlPoAfmCNO_F1g.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx)

Now we need to define titles and unique names (for registering screens in navigation) for each screen and for that, we use `Contants` object which is initialized in `src/utils/contants.ts` file. Let’s open it and make the following changes (you can put any string `prefix` variable as only screen names have to be unique). We are also going to change bottom tabs’ screens’ titles to actual values and add some more colors.

![Image for post](https://miro.medium.com/max/42/1*I0jcPpiAOT-eDWyAOZ2oHQ.png?q=20)

![Image for post](https://miro.medium.com/max/2320/1*I0jcPpiAOT-eDWyAOZ2oHQ.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts)

In order to see our app without errors, we have to make some changes to `src/App.ts` file where we register screens and do some pre-launch stuff like hydrating stores and initializing services.

![Image for post](https://miro.medium.com/max/44/1*FUDOwGzX1cHXwn8A0WodrA.png?q=20)

![Image for post](https://miro.medium.com/max/3028/1*FUDOwGzX1cHXwn8A0WodrA.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/App.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/App.ts)

The last step before going to the next part is to change the default options of navigation as I would love titles to be the same color as tabs. So it is done in `src/services/navigation.ts` and we are going to add more properties to `setDefaultOptions({ ... })` as well as delete some unnecessary methods.

![Image for post](https://miro.medium.com/max/46/1*3KFBahsZt6f893I-9-1cfg.png?q=20)

![Image for post](https://miro.medium.com/max/2252/1*3KFBahsZt6f893I-9-1cfg.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts)

We can remove `src/screens/ExpoScreen.tsx` and `scr/screens/CounterScreen.tsx` as they are from the starter and we don’t need them anymore.

## Subreddits Screen

As we are done with setting up our navigation, we can now start with our first screen `SubredditsScreen.tsx` . On this screen, we are going to have a list of subreddits with a delete option. It should also have an “Add” button which can be added as a right button of a navigation bar. In order to be a bit more user-oriented, we shall add some placeholder for the case when there are no subreddits. Next, we are going to add a new MobX store to manage a state for subreddits as it will be expanded while adding new functionality.

Now we remove `src/stores/counterStore.ts` which is from the starter and add a new file `subredditsStore.ts` . We are going to add one array and two actions (add & delete) to this store for now.

![Image for post](https://miro.medium.com/max/50/1*M6yPVYDvdAaKAfhnLE7OiA.png?q=20)

![Image for post](https://miro.medium.com/max/2588/1*M6yPVYDvdAaKAfhnLE7OiA.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts)

In order to have access to this store within our screens, we need to register it in `src/stores/index.tsx` file.

![Image for post](https://miro.medium.com/max/60/1*De4BtrbY418dObhTD4MUmw.png?q=20)

![Image for post](https://miro.medium.com/max/2220/1*De4BtrbY418dObhTD4MUmw.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/index.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/index.tsx)

Now we can start building our screen. In order to skip some routine by building simple components such as an empty list placeholder or subreddit tile, open the [components folder on Github](https://github.com/kanzitelli/rabbit-app/tree/master/src/components) and copy 3 files to your local folder: [AppleStyleSwipeableRow.js](https://github.com/kanzitelli/rabbit-app/blob/master/src/components/AppleStyleSwipeableRow.js), [EmptyListComponent.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/components/EmptyListComponent.tsx), and [Subreddit.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/components/Subreddit.tsx). As the subreddit component has to have a delete action, I have decided to use something that exists and provides this functionality: Swipeable component from `react-native-gesture-handler` meets all the requirements and is presented in `AppleStyleSwipeableRow.js` file with tiny modifications from my side (some extra props).

Once you are done, open `SubredditsScreen.tsx` and add the code for displaying a list of subreddits and some actions.

![Image for post](https://miro.medium.com/max/52/1*jptfIdFpf2m9jzHpcnuE3w.png?q=20)

![Image for post](https://miro.medium.com/max/3332/1*jptfIdFpf2m9jzHpcnuE3w.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx)

We have some useful hooks (which are available from the starter) such as `useStores()` that gives access to all stores you define; `useServices()` that opens an easy way to get access to services like `navigation; useStyles(_styles)` that returns an object with styles (and theme) depending on the current mode (`dark` or `light`) and it could be used to define your own themes as well. Also one more good thing about the`useStyles()` hook is that it does normalization under the hood (it could be configured not to) meaning all numbers in `_styles` object are going to be normalized to make the app responsive through all sizes of screens (iPhone, iPad). I have really taken advantage of normalization when I have been working on [this app](https://apps.apple.com/ru/app/messenger-for-vk-%D0%B4%D0%BB%D1%8F-%D0%B2%D0%BA/id891605076#?platform=iphone) (you can check screenshots for iPhone and iPad). So no more pain while doing styles. You can also see that styles now have `theme` object which has your predefined colors, sizes, etc.

Now we need to add text for the empty list component to constants as well as options for the`Add` button which will be implemented soon.

![Image for post](https://miro.medium.com/max/60/1*NrJrEMZLqzoT1L13qfBO3Q.png?q=20)

![Image for post](https://miro.medium.com/max/4096/1*NrJrEMZLqzoT1L13qfBO3Q.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts)

You should see the app running but we don’t have any data. So it’s the best time to work on the `Add` button that is going to open modal with text input. Once we add the subreddit, it will be added to the list and a modal will be closed. What we need to do now is to create a new screen with text input, register it, add a method to the navigation service, and the`Add` button itself.

In order to make the process faster, follow [this link](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/TextInputPrompt.tsx), download (copy content) `TextInputPrompt.tsx` file and add it to the`screens` folder. As we are going to use some custom button component in this screen, also download (copy content) [this file](https://github.com/kanzitelli/rabbit-app/blob/master/src/components/Button.tsx) and replace it with existing `src/components/Button.tsx` .

Once you are done, you can add the values to constants and register it.

![Image for post](https://miro.medium.com/max/60/1*bgnClBb28mazKg9AgzgHCg.png?q=20)

![Image for post](https://miro.medium.com/max/2252/1*bgnClBb28mazKg9AgzgHCg.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts)

![Image for post](https://miro.medium.com/max/60/1*oWCroQ-u7wyt85d92YAQ4g.png?q=20)

![Image for post](https://miro.medium.com/max/2388/1*oWCroQ-u7wyt85d92YAQ4g.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts)

![Image for post](https://miro.medium.com/max/60/1*6ToxwIriAN1zh8DAV736BQ.png?q=20)

![Image for post](https://miro.medium.com/max/2892/1*6ToxwIriAN1zh8DAV736BQ.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/App.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/App.ts)

And in order to present this screen, we need to add a button and we are going to use a hook for `react-native-navigation` that simplifies work by listening to navigation’s buttons’ presses.

![Image for post](https://miro.medium.com/max/60/1*R4Ye9mJ4AH4MQuHv3PK32g.png?q=20)

![Image for post](https://miro.medium.com/max/4096/1*R4Ye9mJ4AH4MQuHv3PK32g.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx)

We are almost done with the Subreddits screen, you can play around with adding and removing subreddits. And the only missing thing here is a *push* to a screen with posts of selected subreddit, its value will be passed to `PostsScreen.tsx` . This is what we are going to work on in the following part. Meanwhile, I think it would be a good practice to repeat the same process for `PostsScreen.tsx` as it was done for our first screens while setting up navigation and register that screen in `App.ts` .

## Posts Screen

Assuming that you have added `PostsScreen.tsx` , we need to push the screen with properties (subreddit name) when a subreddit is pressed. First, we are going to define a new type in `utils/types.d.ts` which describes properties that will be sent when a posts screen is pushed.

![Image for post](https://miro.medium.com/max/60/1*S2FVCUUw9XgqkfJppRFonw.png?q=20)

![Image for post](https://miro.medium.com/max/1444/1*S2FVCUUw9XgqkfJppRFonw.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/types.d.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/types.d.ts)

![Image for post](https://miro.medium.com/max/60/1*Ff_CWB85SVTS7lHV-2AvaA.png?q=20)

![Image for post](https://miro.medium.com/max/3400/1*Ff_CWB85SVTS7lHV-2AvaA.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts)

![Image for post](https://miro.medium.com/max/60/1*c8kFCt2pMS0ypjUweTZ21A.png?q=20)

![Image for post](https://miro.medium.com/max/2792/1*c8kFCt2pMS0ypjUweTZ21A.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx)

We can test it now! But… we forgot to somehow display the selected subreddit, let’s say, we will add it as a title for the navigation bar. However, we will use it to fetch some data later.

![Image for post](https://miro.medium.com/max/60/1*h3Dtg88oZm2NcFdPD6K0ww.png?q=20)

![Image for post](https://miro.medium.com/max/3228/1*h3Dtg88oZm2NcFdPD6K0ww.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx)

You can see a new method `generateSubredditString(...)` . It is used to have one unified string format for displaying subreddit name with `r/` , for example, `r/reactnative` . Add this method to `utils/helpMethods.ts` .

![Image for post](https://miro.medium.com/max/60/1*bSTA1gMrFpFV2TXxYmedeQ.png?q=20)

![Image for post](https://miro.medium.com/max/2860/1*bSTA1gMrFpFV2TXxYmedeQ.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/helpMethods.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/helpMethods.ts)

When you push a posts screen, you can see that our title depends on the selected subreddit. The next step is to fetch posts of a subreddit and display them in a list. The first thing we need to start with is to create `api` service that will contain only one method. But to simplify our lives, let’s copy `types.d.ts` and `classes.ts` files from [**here**](https://github.com/kanzitelli/rabbit-app/tree/master/src/utils) to our local `utils` folder, so we don’t spend a lot of time on it. Once you are done, create `api.ts` under `services` folder and check the code below.

![Image for post](https://miro.medium.com/max/60/1*pbPqcFnuV6l5V1pOI9D0Xg.png?q=20)

![Image for post](https://miro.medium.com/max/3332/1*pbPqcFnuV6l5V1pOI9D0Xg.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/services/api.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/services/api.ts)

`getSubredditPosts(...)` function returns a promise with `RedditJsonResponse` result. You can check the type in `types.d.ts` and see that it includes others like a chain. The last one is `RedditPost` where we have the data we need to properly display a post and do all necessary actions. Also, don’t forget to include `api` service in `services/index.tsx` .

As you may have guessed we will need some extra variables in `subredditsStore.ts` . We have an array of strings with all subreddits, and we can have a dictionary (map) to store corresponding posts of a subreddit (subreddit will be a key), for example, `{“react”: {“posts”: [Array]}}` . I wanted to have something like `{“react”: [Array of posts]}` but `mobx-persist` couldn’t handle this case, and I have decided to make it with an extra property `posts` in an object. And in order to use `mobx-persist` properly with your own types, we need to create classes (not types) which you can check in `utils/classes.ts` , they are just copies of types that we have but with extra `persist` decorator.

![Image for post](https://miro.medium.com/max/48/1*R6idMTtqWGJRgkCcni7EqQ.png?q=20)

![Image for post](https://miro.medium.com/max/3500/1*R6idMTtqWGJRgkCcni7EqQ.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts)

We are going to call `getPostsForSubreddit(...)` when posts screen is presented and when we add a new subreddit. I think this is kind of a good practice to pre-fetch (if it doesn’t harm your app’s performance) data to make user’s experience smoother (users don’t like waiting).

![Image for post](https://miro.medium.com/max/60/1*YY_qq5Jjrnpqhkx5BRGHZg.png?q=20)

![Image for post](https://miro.medium.com/max/3228/1*YY_qq5Jjrnpqhkx5BRGHZg.png)

We can check if it actually loads posts and persists all data. That is really good progress. Our next task is to display posts’ tiles in a FlatList. I made it easier and prepared a component that will be used for post’s tile. Please follow this [**link**](https://github.com/kanzitelli/rabbit-app/blob/master/src/components/Post.tsx)**,** download (copy content) `Post.tsx` and save it under `components` folder. As you can see, there are some unknown methods from `utils/helpMethods.ts` which we are going to copy as well. You can check it [**here**](https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/helpMethods.ts) or just download that file and replace it with the existing one. Then you also need to install `dayjs` library (`yarn add dayjs`)as we use it for counting *a time ago* for each post.

![Image for post](https://miro.medium.com/max/54/1*luYihHWTryKveh9jrsZv8g.png?q=20)

![Image for post](https://miro.medium.com/max/3228/1*luYihHWTryKveh9jrsZv8g.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx)

I hope everything looks pretty intuitive and easy, and you can see posts in a list. We are pretty much done with this screen and now can move on to creating a screen for displaying post content. I have chosen a simple path to just use a webview for displaying it. Before proceeding to the next part, we will need to create PostScreen.tsx, register it as we have done before, and install react-native-webview (`yarn add react-native-webview && yarn ios:pods`).

## Post Screen

In this part, we are going to build a screen for displaying a post in webview and it would be cool to have two more features like share and open in a browser. Let’s start with creating a new method in navigation service, pushing a post screen from posts, and setting title depending on passed props.

![Image for post](https://miro.medium.com/max/60/1*7UmhbZcCDOJozsliVgqkag.png?q=20)

![Image for post](https://miro.medium.com/max/2756/1*7UmhbZcCDOJozsliVgqkag.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts)

![Image for post](https://miro.medium.com/max/60/1*FKKMHpx6P8aAv2o4v3Jdug.png?q=20)

![Image for post](https://miro.medium.com/max/3228/1*FKKMHpx6P8aAv2o4v3Jdug.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx)

![Image for post](https://miro.medium.com/max/60/1*fZFYwIlKGMpNKxaiS_0yuw.png?q=20)

![Image for post](https://miro.medium.com/max/3164/1*fZFYwIlKGMpNKxaiS_0yuw.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx)

After finishing those steps, you should be able to push a new post screen with title and subtitle. Now we add webview and display the actual post’s webpage:

![Image for post](https://miro.medium.com/max/52/1*Lil0Tzc7KV6kbcEQ_n9D9g.png?q=20)

![Image for post](https://miro.medium.com/max/3164/1*Lil0Tzc7KV6kbcEQ_n9D9g.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx)

Here I am using `useLocalObservalble` from `mobx-react` for creating a local store with state of the loading indicator. We will show it on the toolbar below webview which will contain two more buttons `Share` and `Open in browser` . For these purposes, we will use `Share` and `Linking` modules from `react-native`.

![Image for post](https://miro.medium.com/max/42/1*VC_XegemqIa2MRE1vNyKDQ.png?q=20)

![Image for post](https://miro.medium.com/max/3164/1*VC_XegemqIa2MRE1vNyKDQ.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx)

And there is one more thing left for this screen which is saving to subreddits store (`saved` array). We are going to show all saved posts in the second tab in the next part. The possibility to save a post means that we should also be able to remove it and check if it is in the saved array. Which is why we will need to make changes to subreddits store by adding `saved` array and corresponding methods, to post screen by adding a button to the navigation bar and to constants.

![Image for post](https://miro.medium.com/max/50/1*h3qpIVTNmShH2hEfm72qKQ.png?q=20)

![Image for post](https://miro.medium.com/max/1476/1*h3qpIVTNmShH2hEfm72qKQ.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts)

![Image for post](https://miro.medium.com/max/60/1*0XhTBfKJBXA81zPtRJWu9Q.png?q=20)

![Image for post](https://miro.medium.com/max/3536/1*0XhTBfKJBXA81zPtRJWu9Q.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts)

![Image for post](https://miro.medium.com/max/60/1*g9__RY8wBFs2pVWOOqyPyg.png?q=20)

![Image for post](https://miro.medium.com/max/3636/1*g9__RY8wBFs2pVWOOqyPyg.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx)

If all steps are followed correctly you should be able to save/remove a post to `saved` array. However, now we are not able to show it inside the app. This is what we are going to do in the next part.

## Saved Screen

We are ready to start working on a screen with saved posts. We already have a component for it and all the logic of the subreddits store from the previous part. They must be displayed as on `PostsScreen.tsx` with only one difference, swipe-to-remove action for each post. And in order to display a saved post, we will reuse a screen from the previous part. However, saved posts mean that it should be cached and available offline but I have a thought that it would be a great future improvement.

Firstly, you need to add the code below to `utils/constants.ts`

![Image for post](https://miro.medium.com/max/60/1*UgKIoN2bq8P5X6HeWGUGjw.png?q=20)

![Image for post](https://miro.medium.com/max/2860/1*UgKIoN2bq8P5X6HeWGUGjw.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts)

And as our logic for saved posts screen is almost the same with posts screen (with one additional function), we can copy the content of this file from [**here**](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SavedScreen.tsx) and enjoy it!

## Settings Screen

We are almost done with our application! The only thing left is a screen with settings. It is nothing special, just a few sections with some useful actions. I already use this simple template in one of my apps and it seems to be working well. And of course, it can be modified in accordance with your needs.

Let’s talk about what we are going to have on the settings screen. There are going to be 3 sections: General (with share, rate, and support actions); Links (with useful links related to the app, e.g. website, privacy policy or others); About (with the current version of the app). We will need to install some packages: one is for app rate action which includes native in-app rating for both platforms, another one is a mail composer from Expo — `yarn add react-native-rate expo-mail-composer && yarn ios:pods` . Rebuild the app as those packages have native dependencies.

As we are going to have 3 sections with the same styles and behavior, it makes sense to create a small component for these purposes. If you follow this [**link**](https://github.com/kanzitelli/rabbit-app/blob/master/src/components/Section.tsx), you will find `Section.tsx` file, please copy the content of it to your local project under `components` folder.

Before we start filling up sections for the settings screen, we need to have some preconfigured options for the app rating, and mail composing actions which will be added to constants, as well as app links, etc.

![Image for post](https://miro.medium.com/max/60/1*vtju8nqasv1BSm8hqlDzZw.png?q=20)

![Image for post](https://miro.medium.com/max/3084/1*vtju8nqasv1BSm8hqlDzZw.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts](https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts)

We are ready to start building our sections. If you are tired and would like to finish with the settings screen asap, you can just copy the content of [**this file**](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx) and paste to `SettingsScreen.tsx` as everything there is very intuitive.

![Image for post](https://miro.medium.com/max/36/1*Uz1CWU9cqGsRRXqSuivexg.png?q=20)

![Image for post](https://miro.medium.com/max/2756/1*Uz1CWU9cqGsRRXqSuivexg.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx)

Note that mail composing doesn’t work on iOS simulators. Other things like a rate action are done easily in one line. So now we just need to add other sections and corresponding methods.

![Image for post](https://miro.medium.com/max/46/1*gmfQ7EC3egyLng7UbES-ZQ.png?q=20)

![Image for post](https://miro.medium.com/max/2724/1*gmfQ7EC3egyLng7UbES-ZQ.png)

[https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx](https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx)

We are done! There are more things I would like to add to this app such as the offline reading of saved articles, push notifications, etc. It should be kind of a playground with the implementation of things that could be helpful when your app goes into production.

# End

As I have published this app to both App Store and Google Play, I thought it would be cool to make a dedicated article to a publishing process; which tools I have used; how to manage expo-updates in production, and other things. And of course, it would make sense to do only if you will find this tutorial useful.

I hope you have learned something new while building the app. If so, I am very happy about that!

Please, feel free to ask me any questions!

[*say\_hi@batyr.io*](mailto:say_hi@batyr.io)*,* [*https://batyr.io*](https://batyr.io)