<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 𝙱𝚊𝚝𝚢𝚛</title>
    <description>The latest articles on DEV Community by 𝙱𝚊𝚝𝚢𝚛 (@kanzitelli).</description>
    <link>https://dev.to/kanzitelli</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F417382%2Fb514254b-bce3-432f-8af2-32558b2376b1.JPG</url>
      <title>DEV Community: 𝙱𝚊𝚝𝚢𝚛</title>
      <link>https://dev.to/kanzitelli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kanzitelli"/>
    <language>en</language>
    <item>
      <title>Build React Native Apps with Simplified and Predictable Navigation</title>
      <dc:creator>𝙱𝚊𝚝𝚢𝚛</dc:creator>
      <pubDate>Tue, 11 Jan 2022 05:35:17 +0000</pubDate>
      <link>https://dev.to/kanzitelli/build-react-native-apps-with-simplified-and-predictable-navigation-5b3j</link>
      <guid>https://dev.to/kanzitelli/build-react-native-apps-with-simplified-and-predictable-navigation-5b3j</guid>
      <description>&lt;p&gt;In this article, we are going to try a new, more simplified and predictable, approach of building a navigation state and moving between screens within an app.&lt;/p&gt;

&lt;p&gt;There are two major navigation libraries in React Native world: &lt;a href="https://reactnavigation.org" rel="noopener noreferrer"&gt;&lt;code&gt;react-navigation&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://wix.github.io/react-native-navigation" rel="noopener noreferrer"&gt;&lt;code&gt;react-native-navigation&lt;/code&gt;&lt;/a&gt;. They are both widely used among the community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RNN Screens&lt;/strong&gt; is not a replacement for any of them but a great addition. It is using React Native Navigation API under the hood and just makes navigation more simplified and predictable with the automatic screens registration and the autocompletion for screen names without any extra work or writing types.&lt;/p&gt;

&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;Below, we are going to initialise a bare React Native app using &lt;a href="https://github.com/react-native-community/cli" rel="noopener noreferrer"&gt;React Native CLI&lt;/a&gt; and add the necessary libraries. After that, we will configure a navigation state, build two components and push/show/pop between them.&lt;/p&gt;

&lt;p&gt;If you'd like to play around with it by your own, feel free to check the &lt;a href="https://github.com/kanzitelli/rnn-screens" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt; and run an example from &lt;code&gt;example/&lt;/code&gt; folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bootstrap React Native app
&lt;/h2&gt;

&lt;p&gt;In order to generate a bare React Native app, we are going to use CLI's init command. Open the terminal, cd to the desired folder and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; npx react-native init RNNScreensExample --template react-native-template-typescript
&amp;gt; cd RNNScreensExample
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The process can take some time. After it's done, change directory to the project and open it in your favourite editor.&lt;/p&gt;
&lt;h2&gt;
  
  
  Install libraries
&lt;/h2&gt;

&lt;p&gt;We need to add &lt;code&gt;rnn-screens&lt;/code&gt; as well as &lt;code&gt;react-native-navigation&lt;/code&gt; as its API is used in RNN Screens.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; yarn add react-native-navigation rnn-screens
&amp;gt; npx rnn-link     # linking RNN
&amp;gt; npx pod-install  # installing pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you had any problems installing React Native Navigation, please follow more &lt;a href="https://wix.github.io/react-native-navigation/docs/installing/" rel="noopener noreferrer"&gt;detailed tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Set up Navigation
&lt;/h2&gt;

&lt;p&gt;As we are done with all the installation steps, it's time to start writing some code.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;index.js&lt;/code&gt; and change with the following:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;code&gt;registerRootComponent&lt;/code&gt; function is the entry point of the whole app. You could see similar functions from React Native and Expo.&lt;/p&gt;

&lt;p&gt;The next step is to create two components: &lt;code&gt;Main&lt;/code&gt; and &lt;code&gt;Settings&lt;/code&gt;. We will push &lt;code&gt;Settings&lt;/code&gt; screen from &lt;code&gt;Main&lt;/code&gt; to show an example of a navigation action. In order to keep it simple, we will be modifying &lt;code&gt;App.tsx&lt;/code&gt; file. You should delete the generated code and paste the one below:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As you can see, we are using &lt;code&gt;screens&lt;/code&gt; variable to &lt;code&gt;push()&lt;/code&gt; and &lt;code&gt;pop()&lt;/code&gt; screens after &lt;code&gt;onPress&lt;/code&gt; button. The next step is to define &lt;code&gt;screens&lt;/code&gt; and describe the appearance (Navigation options) for each screen. We need to add the code in the end of the &lt;code&gt;App.tsx&lt;/code&gt; file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Describing navigation state with pure React Native Navigation API might lead to long and verbose spaghetti-code. This is why it's mandatory to describe a screen's options in one place and application root in another. For example, if you'd want to make a tab based app, you can easily do it like:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Run the app
&lt;/h2&gt;

&lt;p&gt;It's time to run our app with React Native CLI!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; npx react-native run-ios # or
&amp;gt; npx react-native run-android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you had any problems running your app, please follow the more &lt;a href="https://reactnative.dev/docs/environment-setup#running-your-react-native-application" rel="noopener noreferrer"&gt;detailed tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgqa6v73haqug6e862poi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgqa6v73haqug6e862poi.gif" alt="React Native App with RNN Screens" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;This is an experimental library. However, the approach was introduced in &lt;a href="https://github.com/kanzitelli/rnn-starter" rel="noopener noreferrer"&gt;RNN Starter&lt;/a&gt; and showed its success from the very first version.&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions, feel free to contact!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/kanzitelli" rel="noopener noreferrer"&gt;https://twitter.com/kanzitelli&lt;/a&gt; | &lt;a href="https://github.com/kanzitelli" rel="noopener noreferrer"&gt;https://github.com/kanzitelli&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>typescript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Deploying PostgreSQL and Redis behind Traefik in the Cloud</title>
      <dc:creator>𝙱𝚊𝚝𝚢𝚛</dc:creator>
      <pubDate>Mon, 20 Dec 2021 03:09:25 +0000</pubDate>
      <link>https://dev.to/kanzitelli/deploying-postgresql-and-redis-behind-traefik-in-the-cloud-5an2</link>
      <guid>https://dev.to/kanzitelli/deploying-postgresql-and-redis-behind-traefik-in-the-cloud-5an2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Useful for development purposes and faster environment setup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article we are going to deploy &lt;a href="https://www.postgresql.org" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; and &lt;a href="https://redis.io" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; behind &lt;a href="https://doc.traefik.io/traefik/" rel="noopener noreferrer"&gt;Traefik&lt;/a&gt; proxy on a server for $5 and make it available publicly pointing to your subdomain.&lt;/p&gt;

&lt;p&gt;If you'd like to try it out now, here is &lt;a href="https://github.com/kanzitelli/postgres-and-redis-behind-traefik" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;When you start a new project, you will probably need a place to store some data and manage your users' information. There are plenty databases out there but we are going to stick with the most known one - PostgreSQL.&lt;/p&gt;

&lt;p&gt;By the time, when you set up your database and start storing data there, you might also need to have a caching layer on the server that gives you ability to store and access some temporary information like tokens. In order to handle this, you could use Redis which we are going to deploy on par with PostgreSQL behind the Traefik proxy.&lt;/p&gt;

&lt;p&gt;As we are going to deploy our setup on a server, we will make it available for the outside world with the following connection urls:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Postgres:
  Domain: postgresql://admin:pass@db.website.com:5432/db
  IP: postgresql://admin:pass@46.101.120.53:5432/db

Redis:
  Domain: redis://db.website.com:6379
  IP: redis://46.101.120.53:6379


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;So you can have a shared database among the team mates without messing local setups.&lt;/p&gt;

&lt;p&gt;In order to fully complete the guide, you will need to have some familiarity with Terminal and &lt;a href="https://www.docker.com" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;. If you'd like to make PostgreSQL and Redis available from your domain, rather than direct server's IP address, you should have a registered domain and access to a dashboard where you can change DNS records.&lt;/p&gt;


&lt;h2&gt;
  
  
  Setting up a server
&lt;/h2&gt;

&lt;p&gt;We are going to use &lt;a href="https://www.digitalocean.com" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt; to set up a droplet for $5, however, feel free to use any cloud service you like.&lt;/p&gt;

&lt;p&gt;Navigate to a dashboard where you create new droplet and fill in the configurations you prefer. I, personally, use a preconfigured droplet with Docker  from DO's marketplace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhoruufi6ki9dmb02qth4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhoruufi6ki9dmb02qth4.png" alt="Setting up DigitalOcean's new droplet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will also need to specify a name, region and some other configurations for the server. Then, click create and wait till the process is done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxb8mnm0akjqqwlmrvt0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxb8mnm0akjqqwlmrvt0.png" alt="Created droplet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before proceeding to the next step, let's check if we can connect to our droplet through the console. DigitalOcean provides a built-in console, so we can just open it from the browser.&lt;/p&gt;

&lt;p&gt;Press on the droplet to open its configuration, and in the right top corner, you will see &lt;strong&gt;Console&lt;/strong&gt; button. After pressing it, Terminal window connected to the droplet  will pop up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1wtj9uf4ydih3z7cgs1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1wtj9uf4ydih3z7cgs1.png" alt="DigitalOcean console"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Building Docker Compose
&lt;/h2&gt;

&lt;p&gt;After we have set up the server, we can create a &lt;code&gt;docker-compose.yml&lt;/code&gt; file with Traefik, PostgreSQL and Redis services.&lt;/p&gt;

&lt;p&gt;If you are not familiar with Traefik, it's a great proxy server that I use already 3 years for all the projects. Starting from the second version, they have made it possible to configure TCP ports that gives us ability to expose PostreSQL and Redis containers to public.&lt;/p&gt;

&lt;p&gt;Let's start by creating our first Docker Compose service - Traefik. We need to describe entry points for PostgreSQL and Redis containers telling Traefik which ports to use for requests redirection. Other configurations look pretty intuitive and simple. If you'd like to learn more about Traefik, check out &lt;a href="https://doc.traefik.io/traefik/" rel="noopener noreferrer"&gt;the documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After that, we can describe PostgreSQL and Redis services.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;






&lt;h2&gt;
  
  
  Deploying in the Cloud
&lt;/h2&gt;

&lt;p&gt;We have set up our server and prepared the Docker Compose file which we are going to deploy there.&lt;/p&gt;

&lt;p&gt;In order to make the process easy, I have created a &lt;a href="https://github.com/kanzitelli/postgres-and-redis-behind-traefik" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt; which we will clone and just run one command.&lt;/p&gt;

&lt;p&gt;Let's connect to our server (I am going to use DigitalOcean Console) and clone the repository:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;gt; git clone https://github.com/kanzitelli/postgres-and-redis-behind-traefik.git backend
&amp;gt; cd backend


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As we use some environment variables for the Docker Compose setup, we are going to create &lt;code&gt;.env&lt;/code&gt; file and fill it with your values:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;gt; nano .env


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;.env&lt;/code&gt; file should look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

# Postgres
DB_NAME=db
DB_USER=admin
DB_PASS=pass_12345qwerty


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once you have put all the values to the .env file, you can run a build script:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;gt; sh build.sh


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After the building process is finished, you can check which Docker processes are running:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;gt; docker ps


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffyqleoeowead1jacg1mr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffyqleoeowead1jacg1mr.png" alt="docker ps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to make it available publicly we have to create DNS A-record pointing to our server's IP, or you can just use your server's IP address.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff8m0c0msmlw6zdoqz2rm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff8m0c0msmlw6zdoqz2rm.png" alt="DNS A-record"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DNS records update could take up to 72 hours but usually it happens during 5 minutes. If it doesn't want to resolve the host, then try different WiFi or use mobile data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Checking the setup
&lt;/h2&gt;

&lt;p&gt;Now if you open &lt;code&gt;db.website.com:6969&lt;/code&gt;, you will see Traefik's dashboard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6oog7pp296qm95u9qb53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6oog7pp296qm95u9qb53.png" alt="Traefik Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see if everything is running alright by establishing a connection to the database. You can use any PostgreSQL client, I am going to show it in Postico.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1foa589opi7bzoo29clh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1foa589opi7bzoo29clh.png" alt="Postico"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After hitting &lt;strong&gt;Connect&lt;/strong&gt; button, you should see all the tables!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F741dnoq4knbgsxjdyuhb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F741dnoq4knbgsxjdyuhb.png" alt="Postico tables"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Now you can start using your remote PostgreSQL and Redis in your project!&lt;/p&gt;

&lt;p&gt;This approach is very handy for development purposes but close to production conditions. You could measure the latency of connection and other metrics.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Feel free to ask questions, propose any improvements and just say hi!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://batyr.io" rel="noopener noreferrer"&gt;https://batyr.io&lt;/a&gt; | &lt;a href="https://twitter.com/kanzitelli" rel="noopener noreferrer"&gt;https://twitter.com/kanzitelli&lt;/a&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>redis</category>
      <category>traefik</category>
      <category>devops</category>
    </item>
    <item>
      <title>Testing React Native apps with zero effort</title>
      <dc:creator>𝙱𝚊𝚝𝚢𝚛</dc:creator>
      <pubDate>Tue, 12 Jan 2021 21:46:06 +0000</pubDate>
      <link>https://dev.to/kanzitelli/cli-rn-making-rn-app-developing-experience-as-smooth-as-possible-4e98</link>
      <guid>https://dev.to/kanzitelli/cli-rn-making-rn-app-developing-experience-as-smooth-as-possible-4e98</guid>
      <description>&lt;p&gt;Hi folks,&lt;/p&gt;

&lt;p&gt;I am going to introduce a cool and convenient CLI that is aiming to make the React Native app developing experience as smooth as possible. It is &lt;strong&gt;not&lt;/strong&gt; a replacer for react-native CLI but a good addition to it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/kanzitelli/cli-rn" rel="noopener noreferrer"&gt;The project&lt;/a&gt; is currently in the very alpha stage and under heavy testing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Quickstart
&lt;/h2&gt;

&lt;p&gt;In this section, we are going to start using &lt;a href="https://github.com/kanzitelli/cli-rn" rel="noopener noreferrer"&gt;cli-rn&lt;/a&gt; and see it in action!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: I assume that you have some development experience with React Native.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Install &lt;a href="https://github.com/kanzitelli/cli-rn" rel="noopener noreferrer"&gt;cli-rn&lt;/a&gt; globally and generate new app&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; npm i -g cli-rn
&amp;gt; cli-rn new AppName
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It will start generating an app that is bootstrapped from &lt;a href="https://github.com/kanzitelli/rnn-starter" rel="noopener noreferrer"&gt;rnn-starter&lt;/a&gt;. The process is going to take some time.&lt;/p&gt;

&lt;p&gt;Once the process is finished, you will have a production-ready app on your local machine. If you’d like to read more about the app structure and related things, please follow the &lt;a href="https://github.com/kanzitelli/rnn-starter" rel="noopener noreferrer"&gt;rnn-starter page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Let’s assume that you have coded a feature in your app and would like to test it in &lt;strong&gt;release&lt;/strong&gt; mode on a real device to feel the experience of an end-user. We have 2 options here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open XCode and run the project in Release mode (takes ~4–5 minutes).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;a href="https://github.com/kanzitelli/cli-rn" rel="noopener noreferrer"&gt;cli-rn&lt;/a&gt; and &lt;a href="https://apps.apple.com/app/id1548165379" rel="noopener noreferrer"&gt;cli-rn-app&lt;/a&gt; (takes &amp;lt; 1 minute).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you may have guessed, we are going to stick with the second option 🙂&lt;/p&gt;

&lt;p&gt;In order to start testing your app remotely, you will need to download &lt;a href="https://apps.apple.com/app/id1548165379" rel="noopener noreferrer"&gt;cli-rn-app&lt;/a&gt; from the &lt;a href="https://apps.apple.com/app/id1548165379" rel="noopener noreferrer"&gt;App Store&lt;/a&gt;. As an alternative, you can install the most recent version from &lt;a href="https://github.com/kanzitelli/cli-rn-app" rel="noopener noreferrer"&gt;Github&lt;/a&gt; (with a single command &amp;gt; cli-rn app) and also modify it for your needs.&lt;/p&gt;

&lt;p&gt;As was mentioned before, we want to test the app in &lt;strong&gt;release&lt;/strong&gt; mode. In order to achieve it, run the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; cli-rn remote:prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyeiwzf84u3gpujdx2d8a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyeiwzf84u3gpujdx2d8a.png" width="800" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This command will generate an App Code that has to be put in &lt;a href="https://apps.apple.com/app/id1548165379" rel="noopener noreferrer"&gt;cli-rn-app&lt;/a&gt; as shown on the video below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfk15rvlrzyc83bql1wy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfk15rvlrzyc83bql1wy.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://www.youtube.com/embed/ESxQc3wQUAw" rel="noopener noreferrer"&gt;HD quality on Youtube.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After hitting the Run button, you will see the black screen which means that your app started loading.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: seeing the black screen is totally okay as I haven’t found a way to manage it yet &lt;em&gt;🙂&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Voila!&lt;/em&gt; You should be able to see your app! Happy testing 🤙&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apps.apple.com/app/id1548165379" rel="noopener noreferrer"&gt;cli-rn-app&lt;/a&gt; can be reused for testing any of your RN apps. The only thing to keep in mind is that libraries that are installed in &lt;a href="https://github.com/kanzitelli/cli-rn-app" rel="noopener noreferrer"&gt;cli-rn-app&lt;/a&gt; might be not enough for your needs. You can always add it by yourself or &lt;a href="https://github.com/kanzitelli/cli-rn-app/issues" rel="noopener noreferrer"&gt;open an issue&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Working on this project made me learn a lot of things such as writing a CLI for the first time and connecting all parts of the project together, like backend, server for tunneling, mobile app, etc.&lt;/p&gt;

&lt;p&gt;💚 Thanks to &lt;a href="https://reactnative.dev/" rel="noopener noreferrer"&gt;React Native&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💙 Thanks to &lt;a href="https://expo.io/" rel="noopener noreferrer"&gt;Expo&lt;/a&gt; for inspiration&lt;/p&gt;

&lt;p&gt;❤️ Thanks to &lt;a href="https://github.com/wix" rel="noopener noreferrer"&gt;Wix team&lt;/a&gt; for initiating &lt;a href="https://github.com/wix/react-native-navigation" rel="noopener noreferrer"&gt;react-native-navigation&lt;/a&gt; and all contributors for maintaining it&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/cli-rn" rel="noopener noreferrer"&gt;cli-rn&lt;/a&gt; and &lt;a href="https://github.com/kanzitelli/cli-rn-app" rel="noopener noreferrer"&gt;cli-rn-app&lt;/a&gt; saved me a lot of time, I hope they will do the same for you! I will keep working on these tools as they have become essential attributes of my daily developer life. There are some cool features which I’d like to add and, of course, fixing existing issues and improving the codebase will need some time 😇&lt;/p&gt;

&lt;p&gt;I appreciate your time in reading this article. I wish you a great day and Happy Coding 🤙&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cli-rn.batyr.io" rel="noopener noreferrer"&gt;https://cli-rn.batyr.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>reactnativenavigation</category>
      <category>appdevelopment</category>
    </item>
    <item>
      <title>Expo + React Native Navigation</title>
      <dc:creator>𝙱𝚊𝚝𝚢𝚛</dc:creator>
      <pubDate>Sat, 31 Oct 2020 17:44:35 +0000</pubDate>
      <link>https://dev.to/kanzitelli/expo-react-native-navigation-1pll</link>
      <guid>https://dev.to/kanzitelli/expo-react-native-navigation-1pll</guid>
      <description>&lt;h4&gt;
  
  
  Building lite handy Reddit client for iOS and Android using &lt;a href="https://docs.expo.io" rel="noopener noreferrer"&gt;Expo&lt;/a&gt; and &lt;a href="https://wix.github.io/react-native-navigation/" rel="noopener noreferrer"&gt;React Native Navigation&lt;/a&gt;.
&lt;/h4&gt;

&lt;p&gt;Hi guys!&lt;/p&gt;

&lt;p&gt;I am going to walk you through the whole process of building a mobile app using &lt;a href="https://reactnative.dev/" rel="noopener noreferrer"&gt;&lt;strong&gt;React Native&lt;/strong&gt;&lt;/a&gt;. 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 &lt;a href="https://docs.expo.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;Expo SDK&lt;/strong&gt;&lt;/a&gt; with &lt;a href="https://wix.github.io/react-native-navigation/" rel="noopener noreferrer"&gt;&lt;strong&gt;React Native Navigation&lt;/strong&gt;&lt;/a&gt; that gives you a powerful set of tools and truly native navigation. Instead of using the default solution (&lt;a href="https://reactnavigation.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;react-navigation&lt;/strong&gt;&lt;/a&gt;) in Expo (which is great, honestly), I prefer RNN as I love the native feel (iOS &amp;amp; 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 (&lt;a href="https://github.com/kanzitelli/react-native-navigation-mobx-boilerplate" rel="noopener noreferrer"&gt;&lt;strong&gt;old&lt;/strong&gt;&lt;/a&gt;). I have recently released a new version of a boilerplate/starter &lt;a href="https://github.com/kanzitelli/expo-rnn-starter" rel="noopener noreferrer"&gt;&lt;strong&gt;expo-rnn-starter&lt;/strong&gt;&lt;/a&gt; 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 &lt;em&gt;a not so fast&lt;/em&gt; 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 &lt;a href="https://rabbitapp.batyr.io/app" rel="noopener noreferrer"&gt;&lt;strong&gt;Rabbit app&lt;/strong&gt;&lt;/a&gt;, we will use &lt;a href="https://github.com/kanzitelli/expo-rnn-starter" rel="noopener noreferrer"&gt;&lt;strong&gt;expo-rnn-starter&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you would like to try out the app, here are links for &lt;a href="https://apps.apple.com/us/app/rabbit-app-lite-reddit-client/id1535084154" rel="noopener noreferrer"&gt;&lt;strong&gt;App Store&lt;/strong&gt;&lt;/a&gt;  and &lt;a href="https://play.google.com/store/apps/details?id=io.batyr.rabbitapp" rel="noopener noreferrer"&gt;&lt;strong&gt;Google Play&lt;/strong&gt;&lt;/a&gt;  (direct  &lt;a href="https://rabbitapp.batyr.io/android_app.apk" rel="noopener noreferrer"&gt;&lt;strong&gt;.apk file link&lt;/strong&gt;&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;If you would like to dig into the code, here is a link to the &lt;a href="https://github.com/kanzitelli/rabbit-app" rel="noopener noreferrer"&gt;&lt;strong&gt;Github repo&lt;/strong&gt;&lt;/a&gt;. Also, it’s worth saying that it is not going to be a copy-paste tutorial but something like a &lt;em&gt;learn-by-doing&lt;/em&gt; process and approach from an indie developer.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why?
&lt;/h1&gt;

&lt;p&gt;There are two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; I use Reddit quite often and mostly for reading &lt;a href="https://www.reddit.com/r/reactnative" rel="noopener noreferrer"&gt;&lt;strong&gt;r/reactnative&lt;/strong&gt;&lt;/a&gt; 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.&lt;/li&gt;
&lt;li&gt; A year ago I have been working on a &lt;a href="https://medium.com/@kanzitelli/good-news-app-golang-flutter-hummingbird-1949f22b299f" rel="noopener noreferrer"&gt;&lt;strong&gt;side project&lt;/strong&gt;&lt;/a&gt;, trying out &lt;a href="https://flutter.dev/" rel="noopener noreferrer"&gt;&lt;strong&gt;Flutter&lt;/strong&gt;&lt;/a&gt;, and getting some new knowledge in &lt;a href="https://golang.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;Golang&lt;/strong&gt;&lt;/a&gt;. 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 &lt;a href="https://github.com/kanzitelli/good-news-backend" rel="noopener noreferrer"&gt;&lt;strong&gt;good job&lt;/strong&gt;&lt;/a&gt; for my self-progress by learning &lt;a href="https://medium.com/@kanzitelli/good-news-app-backend-in-golang-behind-traefik-reverse-proxy-with-https-available-2165b11467e4" rel="noopener noreferrer"&gt;&lt;strong&gt;how to crawl sites and publishing a server on DigitalOcean behind Traefik proxy&lt;/strong&gt;&lt;/a&gt;. And as a framework for creating mobile apps, I have decided to pick Flutter. So here is the &lt;a href="https://github.com/kanzitelli/good-news-flutter-release" rel="noopener noreferrer"&gt;&lt;strong&gt;Github repo&lt;/strong&gt;&lt;/a&gt; but I have never published it or continued working on other parts of that tutorial because Flutter performance in &lt;strong&gt;release&lt;/strong&gt; 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.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Let’s start
&lt;/h1&gt;

&lt;p&gt;The first thing we need to do is to bootstrap our new app from &lt;a href="https://github.com/kanzitelli/expo-rnn-starter" rel="noopener noreferrer"&gt;&lt;strong&gt;expo-rnn-starter&lt;/strong&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;Open the terminal and follow next steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ cd &amp;lt;to-your-desired-folder&amp;gt;
~ git clone https://github.com/kanzitelli/expo-rnn-starter.git rabbitapp &amp;amp;&amp;amp; cd rabbitapp
~ rm -rf .git # to remove starter's git history
~ yarn &amp;amp;&amp;amp; yarn ios:pods # it might take some time
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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 &lt;a href="https://github.com/mayconmesquita/react-native-rename-next" rel="noopener noreferrer"&gt;&lt;strong&gt;react-native-rename-next&lt;/strong&gt;&lt;/a&gt;, 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):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ react-native-rename-next "rabbitapp" -b io.batyr.rabbitapp
~ yarn ios:pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As mentioned on the main page of the library, we need to change the bundle identifier for iOS in XCode in the General section.&lt;/p&gt;

&lt;p&gt;Now you should be able to successfully launch an app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ yarn ios # or
~ yarn android # or yarn android:release - for release build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  App functionality &amp;amp; structure
&lt;/h2&gt;

&lt;p&gt;Ooops…, I forgot to talk about app functionality and structure.&lt;/p&gt;

&lt;p&gt;This is going to be a &lt;em&gt;very&lt;/em&gt; 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:&lt;/p&gt;

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

&lt;p&gt;The main question here is how we are going to get the data. Basically, I use this pattern to get data from Reddit &lt;code&gt;https://www.reddit.com/r/${subreddit}.json&lt;/code&gt;, for example, &lt;code&gt;https://www.reddit.com/r/reactnative.json&lt;/code&gt;, which gives a &lt;code&gt;.json&lt;/code&gt; 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 &lt;code&gt;/utils/types.d.ts&lt;/code&gt; 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!&lt;/p&gt;

&lt;h1&gt;
  
  
  Coding
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Setting up navigation
&lt;/h2&gt;

&lt;p&gt;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 &lt;code&gt;example-screen.tsx&lt;/code&gt; file in &lt;code&gt;screens&lt;/code&gt; folder and rename them to &lt;code&gt;SubredditsScreen.tsx&lt;/code&gt; , &lt;code&gt;SavedScreen.tsx&lt;/code&gt; and &lt;code&gt;SettingsScreen.tsx&lt;/code&gt; , also change the names of components for each screen, like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b3mn8krwi1fb1zecv5u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b3mn8krwi1fb1zecv5u.png" alt="Image for post" width="60" height="41"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdj4aakrlj4poz9ry1o1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdj4aakrlj4poz9ry1o1r.png" alt="Image for post" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to define titles and unique names (for registering screens in navigation) for each screen and for that, we use &lt;code&gt;Contants&lt;/code&gt; object which is initialized in &lt;code&gt;src/utils/contants.ts&lt;/code&gt; file. Let’s open it and make the following changes (you can put any string &lt;code&gt;prefix&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqqf8wd1tyavg9m8r2l1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqqf8wd1tyavg9m8r2l1.png" alt="Image for post" width="42" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbnzilbt5n51tx6s354g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbnzilbt5n51tx6s354g.png" alt="Image for post" width="800" height="1125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoo3iayzmbi1rrpz1gpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoo3iayzmbi1rrpz1gpo.png" alt="Image for post" width="44" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwmzsslh4mfh8wjrysir.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwmzsslh4mfh8wjrysir.png" alt="Image for post" width="800" height="1109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/App.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/App.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;src/services/navigation.ts&lt;/code&gt; and we are going to add more properties to &lt;code&gt;setDefaultOptions({ ... })&lt;/code&gt; as well as delete some unnecessary methods.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm90q7i877i8eqqaxr51e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm90q7i877i8eqqaxr51e.png" alt="Image for post" width="46" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48kxdlxpdepwgg4146sh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48kxdlxpdepwgg4146sh.png" alt="Image for post" width="800" height="1057"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can remove &lt;code&gt;src/screens/ExpoScreen.tsx&lt;/code&gt; and &lt;code&gt;scr/screens/CounterScreen.tsx&lt;/code&gt; as they are from the starter and we don’t need them anymore.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subreddits Screen
&lt;/h2&gt;

&lt;p&gt;As we are done with setting up our navigation, we can now start with our first screen &lt;code&gt;SubredditsScreen.tsx&lt;/code&gt; . 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.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgzfwgaefrub19zo8xrs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgzfwgaefrub19zo8xrs.png" alt="Image for post" width="50" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3oz2z7cv7fd3eo4gu66u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3oz2z7cv7fd3eo4gu66u.png" alt="Image for post" width="800" height="942"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to have access to this store within our screens, we need to register it in &lt;code&gt;src/stores/index.tsx&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9vze90zyr0en3j5bqpyj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9vze90zyr0en3j5bqpyj.png" alt="Image for post" width="60" height="32"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuby95g7tg1ns7jj9lk6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuby95g7tg1ns7jj9lk6w.png" alt="Image for post" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/index.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/index.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;a href="https://github.com/kanzitelli/rabbit-app/tree/master/src/components" rel="noopener noreferrer"&gt;components folder on Github&lt;/a&gt; and copy 3 files to your local folder: &lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/components/AppleStyleSwipeableRow.js" rel="noopener noreferrer"&gt;AppleStyleSwipeableRow.js&lt;/a&gt;, &lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/components/EmptyListComponent.tsx" rel="noopener noreferrer"&gt;EmptyListComponent.tsx&lt;/a&gt;, and &lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/components/Subreddit.tsx" rel="noopener noreferrer"&gt;Subreddit.tsx&lt;/a&gt;. 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 &lt;code&gt;react-native-gesture-handler&lt;/code&gt; meets all the requirements and is presented in &lt;code&gt;AppleStyleSwipeableRow.js&lt;/code&gt; file with tiny modifications from my side (some extra props).&lt;/p&gt;

&lt;p&gt;Once you are done, open &lt;code&gt;SubredditsScreen.tsx&lt;/code&gt; and add the code for displaying a list of subreddits and some actions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffc1pknol3codutis6alf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffc1pknol3codutis6alf.png" alt="Image for post" width="52" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbyg6191akiu2ydfsca57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbyg6191akiu2ydfsca57.png" alt="Image for post" width="800" height="939"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have some useful hooks (which are available from the starter) such as &lt;code&gt;useStores()&lt;/code&gt; that gives access to all stores you define; &lt;code&gt;useServices()&lt;/code&gt; that opens an easy way to get access to services like &lt;code&gt;navigation; useStyles(_styles)&lt;/code&gt; that returns an object with styles (and theme) depending on the current mode (&lt;code&gt;dark&lt;/code&gt; or &lt;code&gt;light&lt;/code&gt;) and it could be used to define your own themes as well. Also one more good thing about the&lt;code&gt;useStyles()&lt;/code&gt; hook is that it does normalization under the hood (it could be configured not to) meaning all numbers in &lt;code&gt;_styles&lt;/code&gt; 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 &lt;a href="https://apps.apple.com/ru/app/messenger-for-vk-%D0%B4%D0%BB%D1%8F-%D0%B2%D0%BA/id891605076#?platform=iphone" rel="noopener noreferrer"&gt;this app&lt;/a&gt; (you can check screenshots for iPhone and iPad). So no more pain while doing styles. You can also see that styles now have &lt;code&gt;theme&lt;/code&gt; object which has your predefined colors, sizes, etc.&lt;/p&gt;

&lt;p&gt;Now we need to add text for the empty list component to constants as well as options for the&lt;code&gt;Add&lt;/code&gt; button which will be implemented soon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxmyxkhndr6zqr3pudrzf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxmyxkhndr6zqr3pudrzf.png" alt="Image for post" width="60" height="27"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ryruy406z8izbomgezh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ryruy406z8izbomgezh.png" alt="Image for post" width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should see the app running but we don’t have any data. So it’s the best time to work on the &lt;code&gt;Add&lt;/code&gt; 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&lt;code&gt;Add&lt;/code&gt; button itself.&lt;/p&gt;

&lt;p&gt;In order to make the process faster, follow &lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/TextInputPrompt.tsx" rel="noopener noreferrer"&gt;this link&lt;/a&gt;, download (copy content) &lt;code&gt;TextInputPrompt.tsx&lt;/code&gt; file and add it to the&lt;code&gt;screens&lt;/code&gt; folder. As we are going to use some custom button component in this screen, also download (copy content) &lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/components/Button.tsx" rel="noopener noreferrer"&gt;this file&lt;/a&gt; and replace it with existing &lt;code&gt;src/components/Button.tsx&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Once you are done, you can add the values to constants and register it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xac0ufldlyz1p3jpq5w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xac0ufldlyz1p3jpq5w.png" alt="Image for post" width="60" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzhjqkfymfhjhlwopwrcj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzhjqkfymfhjhlwopwrcj.png" alt="Image for post" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16xsrr9nqka8bnanudud.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16xsrr9nqka8bnanudud.png" alt="Image for post" width="60" height="35"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhve9cf03qryt4rwxya0x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhve9cf03qryt4rwxya0x.png" alt="Image for post" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tpjcp2gnthhagoakmaw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tpjcp2gnthhagoakmaw.png" alt="Image for post" width="60" height="23"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fny7pm7m1ise6m3j5k4ty.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fny7pm7m1ise6m3j5k4ty.png" alt="Image for post" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/App.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/App.ts&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7mcn2ychdr2a4f1mbtgz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7mcn2ychdr2a4f1mbtgz.png" alt="Image for post" width="60" height="33"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvfcrh54nj5g47n3pr47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvfcrh54nj5g47n3pr47.png" alt="Image for post" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;em&gt;push&lt;/em&gt; to a screen with posts of selected subreddit, its value will be passed to &lt;code&gt;PostsScreen.tsx&lt;/code&gt; . 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 &lt;code&gt;PostsScreen.tsx&lt;/code&gt; as it was done for our first screens while setting up navigation and register that screen in &lt;code&gt;App.ts&lt;/code&gt; .&lt;/p&gt;

&lt;h2&gt;
  
  
  Posts Screen
&lt;/h2&gt;

&lt;p&gt;Assuming that you have added &lt;code&gt;PostsScreen.tsx&lt;/code&gt; , 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 &lt;code&gt;utils/types.d.ts&lt;/code&gt; which describes properties that will be sent when a posts screen is pushed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91dbpz2f82ikvecos754.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91dbpz2f82ikvecos754.png" alt="Image for post" width="60" height="40"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu2h1wvmu9exd0a6h2z8i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu2h1wvmu9exd0a6h2z8i.png" alt="Image for post" width="722" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/types.d.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/types.d.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frg8flct6t4dkx2auwhkl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frg8flct6t4dkx2auwhkl.png" alt="Image for post" width="60" height="25"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbdu2ms60ba78hzvif4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbdu2ms60ba78hzvif4s.png" alt="Image for post" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqe7squ8uvdw0vt2acue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqe7squ8uvdw0vt2acue.png" alt="Image for post" width="60" height="31"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9vgwqrzuq7bqau072f7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9vgwqrzuq7bqau072f7.png" alt="Image for post" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SubredditsScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fii84dh9hy2n03h5a391h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fii84dh9hy2n03h5a391h.png" alt="Image for post" width="60" height="33"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gl3vqozvyt32ag7v2ql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gl3vqozvyt32ag7v2ql.png" alt="Image for post" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nzll238006rec7mo27r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nzll238006rec7mo27r.png" alt="Image for post" width="60" height="17"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8gmoefxskx2oqxa0sip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8gmoefxskx2oqxa0sip.png" alt="Image for post" width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/helpMethods.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/helpMethods.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;api&lt;/code&gt; service that will contain only one method. But to simplify our lives, let’s copy &lt;code&gt;types.d.ts&lt;/code&gt; and &lt;code&gt;classes.ts&lt;/code&gt; files from &lt;a href="https://github.com/kanzitelli/rabbit-app/tree/master/src/utils" rel="noopener noreferrer"&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt; to our local &lt;code&gt;utils&lt;/code&gt; folder, so we don’t spend a lot of time on it. Once you are done, create &lt;code&gt;api.ts&lt;/code&gt; under &lt;code&gt;services&lt;/code&gt; folder and check the code below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5raqi4z5nrsoanxyuq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5raqi4z5nrsoanxyuq1.png" alt="Image for post" width="60" height="26"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9208fqe0ni71zfrtu9ev.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9208fqe0ni71zfrtu9ev.png" alt="Image for post" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/services/api.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/services/api.ts&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;As you may have guessed we will need some extra variables in &lt;code&gt;subredditsStore.ts&lt;/code&gt; . 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, &lt;code&gt;{“react”: {“posts”: [Array]}}&lt;/code&gt; . I wanted to have something like &lt;code&gt;{“react”: [Array of posts]}&lt;/code&gt; but &lt;code&gt;mobx-persist&lt;/code&gt; couldn’t handle this case, and I have decided to make it with an extra property &lt;code&gt;posts&lt;/code&gt; in an object. And in order to use &lt;code&gt;mobx-persist&lt;/code&gt; properly with your own types, we need to create classes (not types) which you can check in &lt;code&gt;utils/classes.ts&lt;/code&gt; , they are just copies of types that we have but with extra &lt;code&gt;persist&lt;/code&gt; decorator.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fva3qd2r791fdxb2771sh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fva3qd2r791fdxb2771sh.png" alt="Image for post" width="48" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3855vc1xy1t0umccd07z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3855vc1xy1t0umccd07z.png" alt="Image for post" width="800" height="1009"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are going to call &lt;code&gt;getPostsForSubreddit(...)&lt;/code&gt; 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).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nxyhguhm5ninumeh3au.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nxyhguhm5ninumeh3au.png" alt="Image for post" width="60" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsxz9sguzen0fns8lw0r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsxz9sguzen0fns8lw0r.png" alt="Image for post" width="800" height="719"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/components/Post.tsx" rel="noopener noreferrer"&gt;&lt;strong&gt;link&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;,&lt;/strong&gt; download (copy content) &lt;code&gt;Post.tsx&lt;/code&gt; and save it under &lt;code&gt;components&lt;/code&gt; folder. As you can see, there are some unknown methods from &lt;code&gt;utils/helpMethods.ts&lt;/code&gt; which we are going to copy as well. You can check it &lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/helpMethods.ts" rel="noopener noreferrer"&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt; or just download that file and replace it with the existing one. Then you also need to install &lt;code&gt;dayjs&lt;/code&gt; library (&lt;code&gt;yarn add dayjs&lt;/code&gt;)as we use it for counting &lt;em&gt;a time ago&lt;/em&gt; for each post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7wi4n1aha9nwfc0ecut3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7wi4n1aha9nwfc0ecut3.png" alt="Image for post" width="54" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc38avmjwwq6y78rjjz3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc38avmjwwq6y78rjjz3w.png" alt="Image for post" width="800" height="880"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 (&lt;code&gt;yarn add react-native-webview &amp;amp;&amp;amp; yarn ios:pods&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Post Screen
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr42v8rlqfqqzmwu4no0z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr42v8rlqfqqzmwu4no0z.png" alt="Image for post" width="60" height="26"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fugkbil888smtb73fzao8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fugkbil888smtb73fzao8.png" alt="Image for post" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/services/navigation.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw8bq00496w5rappezide.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw8bq00496w5rappezide.png" alt="Image for post" width="60" height="25"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw173zr4fdgw7xi15yf07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw173zr4fdgw7xi15yf07.png" alt="Image for post" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostsScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqk99czkvt3tjtam15lzz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqk99czkvt3tjtam15lzz.png" alt="Image for post" width="60" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawqrvtqndodrcr3kmmug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawqrvtqndodrcr3kmmug.png" alt="Image for post" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7dzu1f1mq3voiqljqce9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7dzu1f1mq3voiqljqce9.png" alt="Image for post" width="52" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbghkb7jcwd3jlsyi45c6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbghkb7jcwd3jlsyi45c6.png" alt="Image for post" width="800" height="934"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here I am using &lt;code&gt;useLocalObservalble&lt;/code&gt; from &lt;code&gt;mobx-react&lt;/code&gt; 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 &lt;code&gt;Share&lt;/code&gt; and &lt;code&gt;Open in browser&lt;/code&gt; . For these purposes, we will use &lt;code&gt;Share&lt;/code&gt; and &lt;code&gt;Linking&lt;/code&gt; modules from &lt;code&gt;react-native&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbrqrop9sj26lrf5vz0d7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbrqrop9sj26lrf5vz0d7.png" alt="Image for post" width="42" height="60"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevr4wn5k8j1s7td7fa71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevr4wn5k8j1s7td7fa71.png" alt="Image for post" width="800" height="1134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And there is one more thing left for this screen which is saving to subreddits store (&lt;code&gt;saved&lt;/code&gt; 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 &lt;code&gt;saved&lt;/code&gt; array and corresponding methods, to post screen by adding a button to the navigation bar and to constants.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6678g0xtym0ggao2oe1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6678g0xtym0ggao2oe1.png" alt="Image for post" width="50" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Facc320ehqhgkzhy8qxjm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Facc320ehqhgkzhy8qxjm.png" alt="Image for post" width="738" height="876"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faexdgo3y57p0u9va9f0r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faexdgo3y57p0u9va9f0r.png" alt="Image for post" width="60" height="46"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzci5rm5rwdjb55df2ual.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzci5rm5rwdjb55df2ual.png" alt="Image for post" width="800" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/stores/subredditsStore.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F506ewx95kwn4nt0rjstd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F506ewx95kwn4nt0rjstd.png" alt="Image for post" width="60" height="60"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyyb1r522q6tc0486j07x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyyb1r522q6tc0486j07x.png" alt="Image for post" width="800" height="797"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/PostScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If all steps are followed correctly you should be able to save/remove a post to &lt;code&gt;saved&lt;/code&gt; 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Saved Screen
&lt;/h2&gt;

&lt;p&gt;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 &lt;code&gt;PostsScreen.tsx&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;Firstly, you need to add the code below to &lt;code&gt;utils/constants.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29s454i69cq4x5lgk9k3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29s454i69cq4x5lgk9k3.png" alt="Image for post" width="60" height="29"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j2ram6pqzleuwiq8kw3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j2ram6pqzleuwiq8kw3.png" alt="Image for post" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SavedScreen.tsx" rel="noopener noreferrer"&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt; and enjoy it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Settings Screen
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 — &lt;code&gt;yarn add react-native-rate expo-mail-composer &amp;amp;&amp;amp; yarn ios:pods&lt;/code&gt; . Rebuild the app as those packages have native dependencies.&lt;/p&gt;

&lt;p&gt;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 &lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/components/Section.tsx" rel="noopener noreferrer"&gt;&lt;strong&gt;link&lt;/strong&gt;&lt;/a&gt;, you will find &lt;code&gt;Section.tsx&lt;/code&gt; file, please copy the content of it to your local project under &lt;code&gt;components&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F633j9c6pdbn7lzl5uzxp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F633j9c6pdbn7lzl5uzxp.png" alt="Image for post" width="60" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2js8dsrubbys0l5vvf8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2js8dsrubbys0l5vvf8.png" alt="Image for post" width="800" height="659"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/utils/constants.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx" rel="noopener noreferrer"&gt;&lt;strong&gt;this file&lt;/strong&gt;&lt;/a&gt; and paste to &lt;code&gt;SettingsScreen.tsx&lt;/code&gt; as everything there is very intuitive.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqt2eoj20lszwzeowbvyo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqt2eoj20lszwzeowbvyo.png" alt="Image for post" width="36" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4drnu4se80sglbej4n0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4drnu4se80sglbej4n0.png" alt="Image for post" width="800" height="1302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfjijqgt7nqqt6hkbz75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfjijqgt7nqqt6hkbz75.png" alt="Image for post" width="46" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2os40gl7tcgo87jmlqv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2os40gl7tcgo87jmlqv6.png" alt="Image for post" width="800" height="1022"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx" rel="noopener noreferrer"&gt;https://github.com/kanzitelli/rabbit-app/blob/master/src/screens/SettingsScreen.tsx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h1&gt;
  
  
  End
&lt;/h1&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;I hope you have learned something new while building the app. If so, I am very happy about that!&lt;/p&gt;

&lt;p&gt;Please, feel free to ask me any questions!&lt;/p&gt;

&lt;p&gt;&lt;a href="//mailto:say_hi@batyr.io"&gt;&lt;em&gt;say_hi@batyr.io&lt;/em&gt;&lt;/a&gt;&lt;em&gt;,&lt;/em&gt; &lt;a href="https://batyr.io" rel="noopener noreferrer"&gt;&lt;em&gt;https://batyr.io&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
