Expo + React Native Navigation? Yes!

Building lite handy Reddit client for iOS and Android using Expo and React Native Navigation.

Why?

There are two reasons:

  1. A year ago I have been working on a side project, trying out Flutter, and getting some new knowledge in Golang. 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 for my self-progress by learning how to crawl sites and publishing a server on DigitalOcean behind Traefik proxy. And as a framework for creating mobile apps, I have decided to pick Flutter. So here is the Github repo 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:

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
~ react-native-rename-next "rabbitapp" -b io.batyr.rabbitapp
~ yarn ios:pods
~ yarn ios # or
~ yarn android # or yarn android:release - for release build

App functionality & structure

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

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

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:

https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx
https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/App.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts

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.

https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/index.tsx
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx
https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/App.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx

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.

https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/types.d.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx
https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/helpMethods.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/services/api.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx

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.

https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx
https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx

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.

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

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.

https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx
https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx

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.

IT Entrepreneur. Open Source Staff. MS in CS. https://batyr.io