<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Expo on Haseeb Majid</title>
    <link>https://haseebmajid.dev/tags/expo/</link>
    <description>Recent content in Expo on Haseeb Majid</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Mon, 04 Mar 2019 00:00:00 +0000</lastBuildDate><atom:link href="https://haseebmajid.dev/tags/expo/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>DrawerNavigator, TabNavigator and StackNavigator with React Navigation</title>
      <link>https://haseebmajid.dev/posts/2019-03-04-drawernavigator-tabnavigator-and-stacknavigator-with-react-navigation/</link>
      <pubDate>Mon, 04 Mar 2019 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2019-03-04-drawernavigator-tabnavigator-and-stacknavigator-with-react-navigation/</guid>
      <description>&lt;p&gt;In this article, we will create a simple React Native (with &lt;a href=&#34;https://expo.io/&#34;&gt;Expo&lt;/a&gt;) application using React
Navigation, for moving between screens/pages within our app. We will create an app which had a Stack Navigator
nested in a Tab Navigator, nested within a Drawer Navigator.&lt;/p&gt;
&lt;p&gt;This might sound a bit complicated so let&amp;rsquo;s take a look gif below.&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2019-03-04-drawernavigator-tabnavigator-and-stacknavigator-with-react-navigation/images/app.gif&#34;
        type=&#34;&#34;
        alt=&#34;GIF of App&#34;
        
      /&gt;&lt;/p&gt;
&lt;p&gt;We have three main pages in the Drawer Navigator Home (purple), Settings (red) and About (blue) pages. Inside
the Home page, we have a Tab Navigator which has two pages, PageA (purple) and PageB (green). Within PageA we have a
Stack Navigator with two pages Main (purple) and Secondary (yellow).&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In this article, we will create a simple React Native (with <a href="https://expo.io/">Expo</a>) application using React
Navigation, for moving between screens/pages within our app. We will create an app which had a Stack Navigator
nested in a Tab Navigator, nested within a Drawer Navigator.</p>
<p>This might sound a bit complicated so let&rsquo;s take a look gif below.</p>
<p><img
        loading="lazy"
        src="/posts/2019-03-04-drawernavigator-tabnavigator-and-stacknavigator-with-react-navigation/images/app.gif"
        type=""
        alt="GIF of App"
        
      /></p>
<p>We have three main pages in the Drawer Navigator Home (purple), Settings (red) and About (blue) pages. Inside
the Home page, we have a Tab Navigator which has two pages, PageA (purple) and PageB (green). Within PageA we have a
Stack Navigator with two pages Main (purple) and Secondary (yellow).</p>
<h2 id="react-navigation">React Navigation</h2>
<p>Is a library that helps you simplify app navigation.
The main reason for using this library is because it&rsquo;s written purely in JavaScript so no native code (Swift/Android)
is required to make it work. Also, it&rsquo;s the
<a href="https://docs.expo.io/versions/latest/guides/routing-and-navigation">recommended navigation library</a> for Expo.</p>
<h2 id="structure">Structure</h2>
<p>The project structure will look like this</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">├── src
</span></span><span class="line"><span class="cl">│   ├── components
</span></span><span class="line"><span class="cl">│   ├── views
</span></span><span class="line"><span class="cl">|   └── MainApp.js
</span></span><span class="line"><span class="cl">├── package.json
</span></span><span class="line"><span class="cl">├── App.js
</span></span></code></pre></div><h2 id="drawer-navigator">Drawer Navigator</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">Ionicons</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;@expo/vector-icons&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">React</span> <span class="nx">from</span> <span class="s2">&#34;react&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">createAppContainer</span><span class="p">,</span> <span class="nx">createDrawerNavigator</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react-navigation&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">CustomDrawerNavigator</span> <span class="nx">from</span> <span class="s2">&#34;./components/CustomDrawerNavigator&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Home</span> <span class="nx">from</span> <span class="s2">&#34;./views/Home&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Settings</span> <span class="nx">from</span> <span class="s2">&#34;./views/Settings&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">About</span> <span class="nx">from</span> <span class="s2">&#34;./views/About&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">MainNavigator</span> <span class="o">=</span> <span class="nx">createDrawerNavigator</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">Home</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">navigationOptions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">drawerIcon</span><span class="o">:</span> <span class="p">({</span> <span class="nx">tintColor</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="nx">Ionicons</span> <span class="nx">name</span><span class="o">=</span><span class="s2">&#34;md-home&#34;</span> <span class="nx">style</span><span class="o">=</span><span class="p">{{</span> <span class="nx">color</span><span class="o">:</span> <span class="nx">tintColor</span> <span class="p">}}</span> <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="nx">drawerLabel</span><span class="o">:</span> <span class="s2">&#34;Home&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nx">screen</span><span class="o">:</span> <span class="nx">Home</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nx">Settings</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">navigationOptions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">drawerIcon</span><span class="o">:</span> <span class="p">({</span> <span class="nx">tintColor</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="nx">Ionicons</span> <span class="nx">name</span><span class="o">=</span><span class="s2">&#34;md-settings&#34;</span> <span class="nx">style</span><span class="o">=</span><span class="p">{{</span> <span class="nx">color</span><span class="o">:</span> <span class="nx">tintColor</span> <span class="p">}}</span> <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="nx">drawerLabel</span><span class="o">:</span> <span class="s2">&#34;Settings&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nx">screen</span><span class="o">:</span> <span class="nx">Settings</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nx">About</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">navigationOptions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">drawerIcon</span><span class="o">:</span> <span class="p">({</span> <span class="nx">tintColor</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">          <span class="o">&lt;</span><span class="nx">Ionicons</span> <span class="nx">name</span><span class="o">=</span><span class="s2">&#34;ios-person&#34;</span> <span class="nx">style</span><span class="o">=</span><span class="p">{{</span> <span class="nx">color</span><span class="o">:</span> <span class="nx">tintColor</span> <span class="p">}}</span> <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="nx">drawerLabel</span><span class="o">:</span> <span class="s2">&#34;About&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nx">screen</span><span class="o">:</span> <span class="nx">About</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">contentComponent</span><span class="o">:</span> <span class="nx">CustomDrawerNavigator</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">MainApp</span> <span class="o">=</span> <span class="nx">createAppContainer</span><span class="p">(</span><span class="nx">MainNavigator</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">MainApp</span><span class="p">;</span>
</span></span></code></pre></div><p>This is where we create our DrawerNavigator with our three main pages, let&rsquo;s take a look at a particular page. Here we
give it the key name <code>Home</code>, the <code>drawerIcon</code> relates to what Icon will be shown in the Drawer Navigator, the <code>drawerLabel</code>
is the name of the page, as shown in the image below. Finally, the <code>screen</code> is the actual &ldquo;jsx&rdquo; the user sees when they
click on the page. By default, the <code>Home</code> page will be the first page the user sees because it is the first page
defined in the navigator.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="nx">Home</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">navigationOptions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">drawerIcon</span><span class="o">:</span> <span class="p">({</span> <span class="nx">tintColor</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">Ionicons</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;md-home&#34;</span> <span class="na">style</span><span class="o">=</span><span class="p">{{</span> <span class="nx">color</span><span class="o">:</span> <span class="nx">tintColor</span> <span class="p">}}</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="nx">drawerLabel</span><span class="o">:</span> <span class="s2">&#34;Home&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">screen</span><span class="o">:</span> <span class="nx">Home</span>
</span></span><span class="line"><span class="cl"><span class="p">},</span>
</span></span></code></pre></div><p><img
        loading="lazy"
        src="/posts/2019-03-04-drawernavigator-tabnavigator-and-stacknavigator-with-react-navigation/images/drawernavigator.png"
        type=""
        alt="The Drawer Navigator"
        
      /></p>
<h3 id="custom-drawer-navigator">Custom Drawer Navigator</h3>
<p>After we&rsquo;ve defined our three pages we then define a custom Drawer Navigator <code>contentComponent: CustomDrawerNavigator</code>.
This is a component we make ourselves and can style it however we wish.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">React</span> <span class="nx">from</span> <span class="s2">&#34;react&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">View</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react-native&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">DrawerItems</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react-navigation&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">styles</span> <span class="nx">from</span> <span class="s2">&#34;./styles&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">CustomDrawerNavigator</span> <span class="o">=</span> <span class="nx">props</span> <span class="p">=&gt;</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">View</span> <span class="na">style</span><span class="o">=</span><span class="p">{[</span><span class="nx">styles</span><span class="p">.</span><span class="nx">container</span><span class="p">]}&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">DrawerItems</span>
</span></span><span class="line"><span class="cl">      <span class="na">activeBackgroundColor</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;black&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="na">activeTintColor</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;white&#34;</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="na">iconContainerStyle</span><span class="o">=</span><span class="p">{</span><span class="nx">styles</span><span class="p">.</span><span class="nx">icons</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span><span class="na">...props</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">View</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">CustomDrawerNavigator</span><span class="p">;</span>
</span></span></code></pre></div><p>Here the <code>DrawerItems</code> are the three pages we&rsquo;ve defined above. We give the active page, the page the user is currently
on, a background of black and a colour of white (the text). The line <code>{...props}</code> is using the
<a href="https://stackoverflow.com/questions/31048953/what-do-these-three-dots-in-react-do">spread operator (&hellip;)</a>,
so we don&rsquo;t have to rewrite all the props passed by React Navigation. For example, we have props like <code>onItemPress</code>
or <code>navigation</code>. This is the same Drawer Navigator shown in the image above.</p>
<h2 id="tab-navigator">Tab Navigator</h2>
<p>So our Tab Navigator allow us to swap pages by changing tabs. The Tab Navigator will be on the home page, so
<code>Home.js</code> has the following code.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">React</span><span class="p">,</span> <span class="p">{</span> <span class="nx">Component</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">View</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react-native&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">CustomTabNavigator</span> <span class="nx">from</span> <span class="s2">&#34;../components/CustomTabNavigator&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">CustomHeader</span> <span class="nx">from</span> <span class="s2">&#34;../components/CustomHeader&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">class</span> <span class="nx">Home</span> <span class="kr">extends</span> <span class="nx">Component</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">static</span> <span class="nx">router</span> <span class="o">=</span> <span class="nx">CustomTabNavigator</span><span class="p">.</span><span class="nx">router</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">View</span> <span class="nx">style</span><span class="o">=</span><span class="p">{{</span> <span class="nx">flex</span><span class="o">:</span> <span class="mi">1</span> <span class="p">}}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">CustomHeader</span> <span class="nx">navigation</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">navigation</span><span class="p">}</span> <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">CustomTabNavigator</span> <span class="nx">navigation</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">navigation</span><span class="p">}</span> <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="err">/View&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="custom-header">Custom Header</h3>
<p>Where the custom header looks like so.</p>
<p><img
        loading="lazy"
        src="/posts/2019-03-04-drawernavigator-tabnavigator-and-stacknavigator-with-react-navigation/images/WhiteHeader.png"
        type=""
        alt="CustomHeader"
        
      /></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">Ionicons</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;@expo/vector-icons&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">React</span> <span class="nx">from</span> <span class="s2">&#34;react&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">View</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react-native&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">styles</span> <span class="nx">from</span> <span class="s2">&#34;./styles&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">CustomHeader</span> <span class="o">=</span> <span class="p">({</span> <span class="nx">navigation</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">View</span> <span class="na">style</span><span class="o">=</span><span class="p">{[</span><span class="nx">styles</span><span class="p">.</span><span class="nx">container</span><span class="p">]}&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">Ionicons</span>
</span></span><span class="line"><span class="cl">      <span class="na">name</span><span class="o">=</span><span class="s">&#34;md-menu&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">size</span><span class="o">=</span><span class="p">{</span><span class="mi">32</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="na">color</span><span class="o">=</span><span class="s">&#34;black&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">onPress</span><span class="o">=</span><span class="p">{()</span> <span class="p">=&gt;</span> <span class="nx">navigation</span><span class="p">.</span><span class="nx">openDrawer</span><span class="p">()}</span>
</span></span><span class="line"><span class="cl">    <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">View</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">CustomHeader</span><span class="p">;</span>
</span></span></code></pre></div><p>This component is just a simple icon, which when pressed, opens the Drawer Navigator using the <code>navigation</code> props we
passed to the component <code>onPress={() =&gt; navigation.openDrawer()}</code>.</p>
<p><strong>Note:</strong> We could also swipe right to open the Drawer Navigator (from the left hand side of the screen).</p>
<p>In the parameters we use the following syntax <code>({ navigation })</code>, this is called
<a href="https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/">destructuring</a>. We can use this with arrays or
objects for example;</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">a</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">b</span><span class="o">:</span> <span class="mi">20</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// We could do
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">a</span> <span class="o">=</span> <span class="nx">temp</span><span class="p">.</span><span class="nx">a</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">b</span> <span class="o">=</span> <span class="nx">temp</span><span class="p">.</span><span class="nx">b</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Or
</span></span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">a</span><span class="p">,</span> <span class="nx">b</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">temp</span><span class="p">;</span>
</span></span></code></pre></div><p>We do as similar thing with the props, rather then referring to <code>navigation</code> as <code>props.navigation</code> and passing a
parameter <code>props</code> instead of <code>({ navigation })</code>, this simplifies our code a little bit and makes it easier to follow.</p>
<h3 id="custom-tab-navigator">Custom Tab Navigator</h3>
<p>The custom Tab Navigator is similar to the <code>MainApp.js</code>&rsquo;s Drawer Navigator.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">createMaterialTopTabNavigator</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react-navigation&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">PageA</span> <span class="nx">from</span> <span class="s2">&#34;../../views/Home/PageA&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">PageB</span> <span class="nx">from</span> <span class="s2">&#34;../../views/Home/PageB&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">CustomTabNavigator</span> <span class="o">=</span> <span class="nx">createMaterialTopTabNavigator</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">PageA</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">navigationOptions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">tabBarLabel</span><span class="o">:</span> <span class="s2">&#34;PageA&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nx">screen</span><span class="o">:</span> <span class="nx">PageA</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nx">PageB</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">navigationOptions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">tabBarLabel</span><span class="o">:</span> <span class="s2">&#34;PageB&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nx">screen</span><span class="o">:</span> <span class="nx">PageB</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">tabBarPosition</span><span class="o">:</span> <span class="s2">&#34;bottom&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">CustomTabNavigator</span><span class="p">;</span>
</span></span></code></pre></div><p>We give it the two pages we want to be &ldquo;navigatable&rdquo; via tabs in this case <code>PageA</code> and <code>PageB</code>, we then define
the tab to be at the bottom (rather than the top) of the screen. By default <code>PageA</code> will be the page we
visit when we go <code>Home</code> page because it&rsquo;s the first page defined in the Tab Navigator.</p>
<hr>
<h2 id="stack-navigator">Stack Navigator</h2>
<p>In this example, PageB (second page on Tab Navigator) is just a simple page. The stack navigator exists on
<code>PageA</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">createStackNavigator</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react-navigation&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Main</span> <span class="nx">from</span> <span class="s2">&#34;./PageA/Main&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Secondary</span> <span class="nx">from</span> <span class="s2">&#34;./PageA/Secondary&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">PageANavigator</span> <span class="o">=</span> <span class="nx">createStackNavigator</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">Main</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">navigationOptions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">header</span><span class="o">:</span> <span class="kc">null</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nx">screen</span><span class="o">:</span> <span class="nx">Main</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">Secondary</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">navigationOptions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">header</span><span class="o">:</span> <span class="kc">null</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nx">screen</span><span class="o">:</span> <span class="nx">Secondary</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">PageANavigator</span><span class="p">.</span><span class="nx">navigationOptions</span> <span class="o">=</span> <span class="p">({</span> <span class="nx">navigation</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">tabBarVisible</span><span class="o">:</span> <span class="nx">navigation</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">index</span> <span class="o">===</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">swipeEnabled</span><span class="o">:</span> <span class="nx">navigation</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">index</span> <span class="o">===</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">PageANavigator</span><span class="p">;</span>
</span></span></code></pre></div><p>Again this is very similar to our other navigators we&rsquo;ve defined. Here we define two pages that we can navigate between,
like before the <code>Main</code> page is the page we visit by default. So the first page the user will see when you open the app
is the <code>Main</code> page. This is because when the app is first opened we visit the <code>Home</code> page (first in the Drawer Navigator),
which contains <code>PageA</code> (first in Tab Navigator), which contains <code>Main</code> (first in Stack Navigator).</p>
<p>In the code, we set <code>header: null</code> else part of the screen will be taken up by a navigation header, as shown in the
image below.</p>
<p><img
        loading="lazy"
        src="/posts/2019-03-04-drawernavigator-tabnavigator-and-stacknavigator-with-react-navigation/images/WhiteHeader.png"
        type=""
        alt="The White Header"
        
      /></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="nx">PageANavigator</span><span class="p">.</span><span class="nx">navigationOptions</span> <span class="o">=</span> <span class="p">({</span> <span class="nx">navigation</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">tabBarVisible</span><span class="o">:</span> <span class="nx">navigation</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">index</span> <span class="o">===</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">swipeEnabled</span><span class="o">:</span> <span class="nx">navigation</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">index</span> <span class="o">===</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>The first page in the Stack Navigator (<code>Main</code>) has an index of 0, so <code>navigation.state.index === 0</code> evaluates as true.
So on the <code>Main</code> page we will see the tab bar and can swipe to change tabs but we cannot do this on the second page
<code>Secondary</code>.</p>
<h3 id="main">Main</h3>
<p>So now we have a Stack Navigator but we have no obvious way to get from <code>Main</code> to <code>Secondary</code>. With the
Drawer Navigator and Tab Navigator, we can press buttons to change.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">React</span><span class="p">,</span> <span class="p">{</span> <span class="nx">Component</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">Button</span><span class="p">,</span> <span class="nx">View</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react-native&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">class</span> <span class="nx">Main</span> <span class="kr">extends</span> <span class="nx">Component</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">View</span> <span class="nx">style</span><span class="o">=</span><span class="p">{{</span> <span class="nx">flex</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">backgroundColor</span><span class="o">:</span> <span class="s2">&#34;purple&#34;</span> <span class="p">}}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">Button</span>
</span></span><span class="line"><span class="cl">          <span class="nx">title</span><span class="o">=</span><span class="s2">&#34;To Secondary&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="nx">onPress</span><span class="o">=</span><span class="p">{()</span> <span class="p">=&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">navigation</span><span class="p">.</span><span class="nx">navigate</span><span class="p">(</span><span class="s2">&#34;Secondary&#34;</span><span class="p">)}</span>
</span></span><span class="line"><span class="cl">        <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="err">/View&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can do this by creating our button in <code>Main</code> which when pressed navigates us to <code>Secondary</code> page,
<code>onPress={() =&gt; this.props.navigation.navigate(&quot;Secondary&quot;)}</code>. Where &ldquo;Secondary&rdquo; is the page name to
change to.</p>
<h2 id="other-pages">Other Pages</h2>
<p>All the other pages are very basic and look something like this, simple background and not much else.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">React</span><span class="p">,</span> <span class="p">{</span> <span class="nx">Component</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">View</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;react-native&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">CustomHeader</span> <span class="nx">from</span> <span class="s2">&#34;../components/CustomHeader&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">class</span> <span class="nx">Settings</span> <span class="kr">extends</span> <span class="nx">Component</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">View</span> <span class="nx">style</span><span class="o">=</span><span class="p">{{</span> <span class="nx">flex</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">backgroundColor</span><span class="o">:</span> <span class="s2">&#34;red&#34;</span> <span class="p">}}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">CustomHeader</span> <span class="nx">navigation</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">navigation</span><span class="p">}</span> <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="err">/View&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/hmajid2301/blog/-/tree/main/content/posts/2019-03-04-drawernavigator-tabnavigator-and-stacknavigator-with-react-navigation/source_code">Example source code</a></li>
<li><a href="https://reactnavigation.org/">React Navigation</a></li>
<li><a href="https://www.genymotion.com/">Genymotion emulator</a></li>
<li>GIFs created with <a href="https://www.screentogif.com/">screentogif</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>Theme your Expo/React Native App with Redux and React Navigation</title>
      <link>https://haseebmajid.dev/posts/2018-12-23-theme-your-expo-react-native-app-with-redux-and-react-navigation/</link>
      <pubDate>Sun, 23 Dec 2018 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2018-12-23-theme-your-expo-react-native-app-with-redux-and-react-navigation/</guid>
      <description>&lt;p&gt;Recently whilst developing a React Native app (with Expo),
I built a simple tab navigator using React Navigation library.
I wanted to theme the app so that the header would change colour depending on which page you&amp;rsquo;re on.
For example on the primary page it would be red and on the secondary page, when you change tabs, the
header would become blue.&lt;/p&gt;
&lt;p&gt;I ended up being able to do it using Redux. In this article, I will show you how you can theme your Expo
app using Redux with React Navigation.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Recently whilst developing a React Native app (with Expo),
I built a simple tab navigator using React Navigation library.
I wanted to theme the app so that the header would change colour depending on which page you&rsquo;re on.
For example on the primary page it would be red and on the secondary page, when you change tabs, the
header would become blue.</p>
<p>I ended up being able to do it using Redux. In this article, I will show you how you can theme your Expo
app using Redux with React Navigation.</p>
<p>This article is written in British English however, the code is written using American English to make it more consistent (colour vs color).</p>
<h2 id="react-navigation">React Navigation</h2>
<p>Is a library that helps you simplify app navigation.
The main reason for using this library is because it&rsquo;s written purely in JavaScript so no native code (Swift/Android) is required to make it work. Also, it&rsquo;s the <a href="https://docs.expo.io/versions/latest/guides/routing-and-navigation">recommended navigation library</a> for Expo.</p>
<h2 id="redux">Redux</h2>
<p><a href="https://redux.js.org/">Redux</a> is used to manage global state across a React app, it can actually be used with both React and React Native. Of course, in this example, we will be using Redux with a React Native app.</p>
<p><img
    loading="lazy"
    src="https://css-tricks.com/wp-content/uploads/2016/03/redux-article-3-01.svg"
    alt="Redux Store, from https://css-tricks.com/learning-react-redux/"
    
  /></p>
<p>The diagram above explains pretty well why you may need to use Redux. Passing state can be tricky
in more complicated React Native apps, with lots of components and sub-components. Using redux
we can change the state in one component and Redux will update the state in all the other components.</p>
<p>There are many great tutorials about Redux, I particularly liked this <a href="https://www.youtube.com/watch?v=KcC8KZ_Ga2M">one</a>.
Here is brief summary how Redux will work with this app.</p>
<ul>
<li>Redux sets the initial (state) colour to red</li>
<li>Change tabs from main to the secondary page</li>
<li>This dispatches an action to the Redux store (action is called <code>toggleTheme</code>)</li>
<li>The store then calls a reducer</li>
<li>The reducer (also called <code>toggleTheme</code>) updates the old state to a new state, it changes the colour from red to blue</li>
<li>Redux updates the state in all the components</li>
</ul>
<p>Here is a GIF that might help clear up how it work.</p>
<p><img
    loading="lazy"
    src="https://camo.githubusercontent.com/5aba89b6daab934631adffc1f301d17bb273268b/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6d656469612d702e736c69642e65732f75706c6f6164732f3336343831322f696d616765732f323438343535322f415243482d5265647578322d7265616c2e676966"
    alt="Redux Flow, from http://slides.com/jenyaterpil/redux-from-twitter-hype-to-production#"
    
  /></p>
<h2 id="prerequisite">Prerequisite</h2>
<ul>
<li>An Expo/React Native app</li>
<li>An Android emulator/device to test on</li>
<li>Install the following dependencies</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">&#34;react-navigation&#34;: &#34;^2.18.0&#34;,
</span></span><span class="line"><span class="cl">&#34;react-redux&#34;: &#34;^5.1.1&#34;,
</span></span><span class="line"><span class="cl">&#34;redux&#34;: &#34;^4.0.1&#34;,
</span></span></code></pre></div><h2 id="solution">Solution</h2>
<p>Now to the interesting part of this article let&rsquo;s take a look at the code.</p>
<h3 id="structure">Structure</h3>
<p>The project structure will look like this</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">├── src
</span></span><span class="line"><span class="cl">│   ├── actions
</span></span><span class="line"><span class="cl">│   ├── components
</span></span><span class="line"><span class="cl">│   ├── containers
</span></span><span class="line"><span class="cl">│   ├── reducers
</span></span><span class="line"><span class="cl">│   ├── screens
</span></span><span class="line"><span class="cl">│   ├── store
</span></span><span class="line"><span class="cl">|   └── themes
</span></span><span class="line"><span class="cl">├── package.json
</span></span><span class="line"><span class="cl">├── App.js
</span></span></code></pre></div><h3 id="themes">themes</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">const</span> <span class="nx">COLORS</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">red</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&#34;red&#34;</span><span class="p">,</span> <span class="nx">hexCode</span><span class="o">:</span> <span class="s2">&#34;#DE5448&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">blue</span><span class="o">:</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&#34;blue&#34;</span><span class="p">,</span> <span class="nx">hexCode</span><span class="o">:</span> <span class="s2">&#34;#498AF4&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>Here we define our two colours that will be used as themes, red and blue. I have given each colour a name because it makes the toggle logic easier to follow.</p>
<h3 id="reducers">reducers</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">COLORS</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;../themes&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">initialState</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">colorData</span><span class="o">:</span> <span class="nx">COLORS</span><span class="p">.</span><span class="nx">red</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">Theme</span> <span class="o">=</span> <span class="p">(</span><span class="nx">state</span> <span class="o">=</span> <span class="nx">initialState</span><span class="p">,</span> <span class="nx">action</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">switch</span> <span class="p">(</span><span class="nx">action</span><span class="p">.</span><span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="s1">&#39;TOGGLE_THEME&#39;</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">      <span class="k">switch</span><span class="p">(</span><span class="nx">action</span><span class="p">.</span><span class="nx">payload</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="s1">&#39;red&#39;</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">          <span class="k">return</span> <span class="p">{</span> <span class="nx">colorData</span><span class="o">:</span> <span class="nx">COLORS</span><span class="p">.</span><span class="nx">blue</span> <span class="p">};</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="s1">&#39;blue&#39;</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">          <span class="k">return</span> <span class="p">{</span> <span class="nx">colorData</span><span class="o">:</span> <span class="nx">COLORS</span><span class="p">.</span><span class="nx">red</span> <span class="p">};</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">default</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="nx">state</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">Theme</span><span class="p">;</span>
</span></span></code></pre></div><p>A reducer is a pure function which takes some state and returns a new state. In this example
it gets passed the current theme colour and swaps it to the new theme colour.</p>
<p>In this example if the action is <code>TOGGLE_THEME</code>, we get the colour name from the payload and using a switch
statement we swap the colours over. So if the current colour is red we update the state (<code>colorData</code>) to be
blue.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">combineReducers</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;redux&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Theme</span> <span class="nx">from</span> <span class="s1">&#39;./Theme&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">combineReducers</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">Theme</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Here we combine all of our reducers, in this example, we are only using the one reducer but if we had multiple reducers, The <code>combineReducers</code> function to would be necessary to combine them together. In this
example we can simply add new reducers to the function as and when we need them.</p>
<h3 id="actions">actions</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">const</span> <span class="nx">TOGGLE_THEME</span> <span class="o">=</span> <span class="s2">&#34;TOGGLE_THEME&#34;</span><span class="p">;</span>
</span></span></code></pre></div><p>This file defines all the actions we can dispatch to our store. In this example, we only need one action to
toggle our theme.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">TOGGLE_THEME</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;./actionTypes&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">const</span> <span class="nx">toggleTheme</span> <span class="o">=</span> <span class="nx">theme</span> <span class="p">=&gt;</span> <span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">type</span><span class="o">:</span> <span class="nx">TOGGLE_THEME</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">payload</span><span class="o">:</span> <span class="nx">theme</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>In this file, we define our actions, so here we have a single action <code>toggleTheme</code>, which takes a
theme as input and passes it as our payload, hence to access the name of the colour we use <code>action.payload.name</code> in our reducer.</p>
<h3 id="store">store</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">createStore</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;redux&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">rootReducer</span> <span class="nx">from</span> <span class="s1">&#39;../reducers&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">store</span> <span class="o">=</span> <span class="nx">createStore</span><span class="p">(</span><span class="nx">rootReducer</span><span class="p">);</span>
</span></span></code></pre></div><p>The Redux store is used to store the current state for our app, we have to link our store with our reducers we can do this using the <code>createStore</code> function and import the reducers from <code>reducers/index.js</code>.</p>
<h3 id="appjs">App.js</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">React</span><span class="p">,</span> <span class="p">{</span> <span class="nx">Component</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;react&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">Provider</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;react-redux&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">store</span> <span class="nx">from</span> <span class="s1">&#39;./src/store&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">CustomTabNavigator</span> <span class="nx">from</span> <span class="s1">&#39;./src/components/CustomTabNavigator&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">class</span> <span class="nx">App</span> <span class="kr">extends</span> <span class="nx">Component</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">Provider</span> <span class="nx">store</span><span class="o">=</span><span class="p">{</span><span class="nx">store</span><span class="p">}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">CustomTabNavigator</span> <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="err">/Provider&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>This acts as the main file for our app, to use Redux with our app we must wrap around <code>Provider</code> tags and
set the store props to our <code>store/index.js</code> file. The <code>&lt;CustomTabNavigator&gt;</code> contains the logic for our two screens and the tab navigator.</p>
<h3 id="components">components</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">store</span> <span class="nx">from</span> <span class="s1">&#39;../store&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">createMaterialTopTabNavigator</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;react-navigation&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">PageA</span> <span class="nx">from</span> <span class="s1">&#39;../screens/PageA&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">PageB</span> <span class="nx">from</span> <span class="s1">&#39;../screens/PageB&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">COLORS</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;../themes&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">toggleTheme</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;../actions&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">commonTabOptions</span> <span class="o">=</span> <span class="nx">color</span> <span class="p">=&gt;</span> <span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">activeTintColor</span><span class="o">:</span> <span class="s1">&#39;white&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pressColor</span><span class="o">:</span> <span class="s1">&#39;#fff&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">inactiveTintColor</span><span class="o">:</span> <span class="s1">&#39;#ddd&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">style</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">backgroundColor</span><span class="o">:</span> <span class="nx">color</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">CustomerTabNavigator</span> <span class="o">=</span> <span class="nx">createMaterialTopTabNavigator</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">Encoding</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">screen</span><span class="o">:</span> <span class="nx">PageA</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">navigationOptions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">tabBarLabel</span><span class="o">:</span> <span class="s1">&#39;A&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">tabBarOptions</span><span class="o">:</span> <span class="nx">commonTabOptions</span><span class="p">(</span><span class="nx">COLORS</span><span class="p">.</span><span class="nx">red</span><span class="p">.</span><span class="nx">hexCode</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">      <span class="nx">tabBarOnPress</span><span class="o">:</span> <span class="p">({</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">defaultHandler</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">store</span><span class="p">.</span><span class="nx">dispatch</span><span class="p">(</span><span class="nx">toggleTheme</span><span class="p">(</span><span class="nx">COLORS</span><span class="p">.</span><span class="nx">blue</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">        <span class="nx">defaultHandler</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">Decoding</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">screen</span><span class="o">:</span> <span class="nx">PageB</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">navigationOptions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">tabBarLabel</span><span class="o">:</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">tabBarOptions</span><span class="o">:</span> <span class="nx">commonTabOptions</span><span class="p">(</span><span class="nx">COLORS</span><span class="p">.</span><span class="nx">blue</span><span class="p">.</span><span class="nx">hexCode</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">      <span class="nx">tabBarOnPress</span><span class="o">:</span> <span class="p">({</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">defaultHandler</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">store</span><span class="p">.</span><span class="nx">dispatch</span><span class="p">(</span><span class="nx">toggleTheme</span><span class="p">(</span><span class="nx">COLORS</span><span class="p">.</span><span class="nx">red</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">        <span class="nx">defaultHandler</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">},</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">tabBarPosition</span><span class="o">:</span> <span class="s1">&#39;bottom&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">CustomerTabNavigator</span><span class="p">;</span>
</span></span></code></pre></div><p>Here is where we use react navigation to create our tab navigator. We define two screens called A and B,
each screen has a different tab colour, red for A and blue for B. The main part of this file is the following</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="nx">tabBarOnPress</span><span class="o">:</span> <span class="p">({</span> <span class="nx">defaultHandler</span> <span class="p">})</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">store</span><span class="p">.</span><span class="nx">dispatch</span><span class="p">(</span><span class="nx">toggleTheme</span><span class="p">(</span><span class="nx">COLORS</span><span class="p">.</span><span class="nx">red</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="nx">defaultHandler</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">},</span>
</span></span></code></pre></div><p>On tab change (from A -&gt; B), we detect the tab press and dispatch the <code>toggleTheme</code> action to the Redux
store. So when we change tabs from A -&gt; B the colour in the store will change from Red -&gt; Blue and
vice versa for B -&gt; A.</p>
<p>One other thing to note is the tab colour is set using the following function. The colour is passed by the <code>tabBarOptions</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">commonTabOptions</span> <span class="o">=</span> <span class="p">(</span><span class="nx">color</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">activeTintColor</span><span class="o">:</span> <span class="s2">&#34;white&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pressColor</span><span class="o">:</span> <span class="s2">&#34;#fff&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">inactiveTintColor</span><span class="o">:</span> <span class="s2">&#34;#ddd&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">style</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">backgroundColor</span><span class="o">:</span> <span class="nx">color</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="nx">tabBarOptions</span><span class="o">:</span> <span class="nx">commonTabOptions</span><span class="p">(</span><span class="nx">COLORS</span><span class="p">.</span><span class="nx">red</span><span class="p">.</span><span class="nx">hexCode</span><span class="p">);</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">React</span><span class="p">,</span> <span class="p">{</span> <span class="nx">Component</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;react&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">View</span><span class="p">,</span> <span class="nx">Button</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;react-native&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">connect</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;react-redux&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">toggleTheme</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;../actions&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">ToggleTheme</span> <span class="kr">extends</span> <span class="nx">Component</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="nx">View</span> <span class="nx">style</span><span class="o">=</span><span class="p">{{</span><span class="nx">marginTop</span><span class="o">:</span> <span class="mi">25</span><span class="p">}}</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">&lt;</span><span class="nx">Button</span>
</span></span><span class="line"><span class="cl">          <span class="nx">title</span><span class="o">=</span><span class="s2">&#34;Toggle Color&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="nx">color</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">color</span><span class="p">.</span><span class="nx">hexCode</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="nx">onPress</span><span class="o">=</span><span class="p">{()</span> <span class="p">=&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">toggleTheme</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">color</span><span class="p">)}</span>
</span></span><span class="line"><span class="cl">        <span class="o">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="o">&lt;</span><span class="err">/View&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">mapStateToProps</span> <span class="o">=</span> <span class="nx">state</span> <span class="p">=&gt;</span> <span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">color</span><span class="o">:</span> <span class="nx">state</span><span class="p">.</span><span class="nx">Theme</span><span class="p">.</span><span class="nx">colorData</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">mapDispatchToProps</span> <span class="o">=</span> <span class="nx">dispatch</span> <span class="p">=&gt;</span> <span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">toggleTheme</span><span class="o">:</span> <span class="nx">color</span> <span class="p">=&gt;</span> <span class="nx">dispatch</span><span class="p">(</span><span class="nx">toggleTheme</span><span class="p">(</span><span class="nx">color</span><span class="p">)),</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">connect</span><span class="p">(</span><span class="nx">mapStateToProps</span><span class="p">,</span> <span class="nx">mapDispatchToProps</span><span class="p">)(</span><span class="nx">ToggleTheme</span><span class="p">);</span>
</span></span></code></pre></div><p>This file does most of the heavy lifting for this app, this is where most of the logic sits. So, first of all, we have a button, which calls <code>toggleTheme</code> on a press of the and passes the current colour (state) as an argument.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">Button</span>
</span></span><span class="line"><span class="cl">  <span class="na">title</span><span class="o">=</span><span class="s">&#34;Toggle Color&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="na">color</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">color</span><span class="p">.</span><span class="nx">hexCode</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="na">onPress</span><span class="o">=</span><span class="p">{()</span> <span class="p">=&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">toggleTheme</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">color</span><span class="p">)}</span>
</span></span><span class="line"><span class="cl"><span class="p">/&gt;</span>
</span></span></code></pre></div><p>The colour of the button is also using the current (state) colour, so in this case, it will start off as red, <code>this.props.color</code>. We can access the current state using <code>this.props</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">mapStateToProps</span> <span class="o">=</span> <span class="p">(</span><span class="nx">state</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">color</span><span class="o">:</span> <span class="nx">state</span><span class="p">.</span><span class="nx">Theme</span><span class="p">.</span><span class="nx">colorData</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>This function is used to map the Redux store to the state of this component. We map <code>state.Theme.colorData</code>,
where <code>Theme</code> is the name of our reducer and <code>colorData</code> is the item name. In this example, we&rsquo;ve mapped the current <code>colorData</code> to <code>color</code> props in this component.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">mapDispatchToProps</span> <span class="o">=</span> <span class="p">(</span><span class="nx">dispatch</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">toggleTheme</span><span class="o">:</span> <span class="p">(</span><span class="nx">color</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">dispatch</span><span class="p">(</span><span class="nx">toggleTheme</span><span class="p">(</span><span class="nx">color</span><span class="p">)),</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>This function maps a function to an action (and dispatches it), in this example when the <code>toggleTheme</code> function is called in the component it will dispatch the <code>toggleTheme</code> action to redux. So when the
button is pressed it will dispatch an action to toggle the theme.</p>
<h3 id="pagea">PageA</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">React</span><span class="p">,</span> <span class="p">{</span> <span class="nx">Component</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;react&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">View</span><span class="p">,</span> <span class="nx">Text</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;react-native&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">ToggleTheme</span> <span class="nx">from</span> <span class="s1">&#39;../components/ToggleTheme&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">class</span> <span class="nx">PageA</span> <span class="kr">extends</span> <span class="nx">Component</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">View</span> <span class="na">style</span><span class="o">=</span><span class="p">{{</span> <span class="nx">flex</span><span class="o">:</span> <span class="mi">1</span> <span class="p">}}&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">ToggleTheme</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">Text</span><span class="p">&gt;</span><span class="nx">PageA</span><span class="p">&lt;/</span><span class="nt">Text</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">View</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This is an example of one of our screens, it&rsquo;s very simple just the page name and <code>&lt;ToggleTheme&gt;</code> component.</p>
<h2 id="example">Example</h2>
<p><img
        loading="lazy"
        src="/posts/2018-12-23-theme-your-expo-react-native-app-with-redux-and-react-navigation/images/example.gif"
        type=""
        alt="example"
        
      /></p>
<p>Here is an example of the app running, as you can see there are two ways we can toggle the theme. We
could use the button click, or change tabs.</p>
<p><em>Extra Task</em>: If you want some practice, currently this won&rsquo;t detect a swipe action to change tabs
look at how you can do this. An example of it working can be found <a href="https://gitlab.com/hmajid2301/stegappasaurus/blob/development/src/screens/Decoding.js">here</a>.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/hmajid2301/blog/-/tree/main/content/posts/2018-12-23-theme-your-expo-react-native-app-with-redux-and-react-navigation/source_code">Example source code</a></li>
<li><a href="https://reactnavigation.org/">React Navigation</a></li>
<li><a href="https://css-tricks.com/learning-react-redux/">Redux Animation</a></li>
<li><a href="http://slides.com/jenyaterpil/redux-from-twitter-hype-to-production#">Redux Diagram</a></li>
<li><a href="https://redux.js.org/">Redux</a></li>
<li>GIFs created with <a href="https://www.screentogif.com/">screentogif</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>Running Expo/React Native in Docker</title>
      <link>https://haseebmajid.dev/posts/2018-10-31-running-expo-react-native-in-docker/</link>
      <pubDate>Wed, 31 Oct 2018 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2018-10-31-running-expo-react-native-in-docker/</guid>
      <description>&lt;p&gt;Running Expo/React Native in a Docker container can sometimes cause issues. In this example, I will be running
Docker 🐳 within a guest VM (Ubuntu) which will run on my host machine (Windows). My host machine will also
be running another VM as the Android emulator (Genymotion) for Expo to connect to. You can get a more
detailed post about how to connect two VMs together
&lt;a href=&#34;https://haseebmajid.dev/posts/react-native-with-virtualbox/&#34;&gt;here&lt;/a&gt;,
#Plug 🔌🔌🔌. Since I&amp;rsquo;ve set up networking on those two VMs already as far as Expo is concerned
it might as well be running on the host machine (Windows). Also in this example, I will be testing
this on an Android device.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Running Expo/React Native in a Docker container can sometimes cause issues. In this example, I will be running
Docker 🐳 within a guest VM (Ubuntu) which will run on my host machine (Windows). My host machine will also
be running another VM as the Android emulator (Genymotion) for Expo to connect to. You can get a more
detailed post about how to connect two VMs together
<a href="https://haseebmajid.dev/posts/react-native-with-virtualbox/">here</a>,
#Plug 🔌🔌🔌. Since I&rsquo;ve set up networking on those two VMs already as far as Expo is concerned
it might as well be running on the host machine (Windows). Also in this example, I will be testing
this on an Android device.</p>
<p><img
        loading="lazy"
        src="/posts/2018-10-31-running-expo-react-native-in-docker/images/docker-nyan.gif"
        type=""
        alt="Original Image: https://maraaverick.rbind.io/2017/11/docker-izing-your-work-in-r/ and https://tutuappapkdownload.com/expo-apk/"
        
      /></p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li><a href="https://docs.docker.com/install/">Install Docker</a></li>
<li>(optional) <a href="https://docs.docker.com/compose/install/">Install docker-compose</a></li>
<li>Android device/emulator to test on</li>
</ul>
<h2 id="docker">Docker</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;main&#34;</span><span class="p">:</span> <span class="s2">&#34;node_modules/expo/AppEntry.js&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;private&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;scripts&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;android&#34;</span><span class="p">:</span> <span class="s2">&#34;expo-cli start --android&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;ios&#34;</span><span class="p">:</span> <span class="s2">&#34;expo-cli start --ios&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;start&#34;</span><span class="p">:</span> <span class="s2">&#34;expo-cli start&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;dependencies&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;expo&#34;</span><span class="p">:</span> <span class="s2">&#34;30.0.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;expo-cli&#34;</span><span class="p">:</span> <span class="s2">&#34;2.2.4&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;react&#34;</span><span class="p">:</span> <span class="s2">&#34;16.3.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;react-native&#34;</span><span class="p">:</span> <span class="s2">&#34;https://github.com/expo/react-native/archive/sdk-30.0.0.tar.gz&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The <code>package.json</code> file I will be using the following example is a very barebones file, just including the minimum
packages required to run Expo.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-docker" data-lang="docker"><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"> </span><span class="s">node:latest</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="k">LABEL</span> <span class="nv">version</span><span class="o">=</span><span class="m">1</span>.2.1<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="k">ENV</span> <span class="nv">ADB_IP</span><span class="o">=</span><span class="s2">&#34;192.168.1.1&#34;</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="k">ENV</span> <span class="nv">REACT_NATIVE_PACKAGER_HOSTNAME</span><span class="o">=</span><span class="s2">&#34;192.255.255.255&#34;</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="k">EXPOSE</span><span class="w"> </span><span class="s">19000</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="k">EXPOSE</span><span class="w"> </span><span class="s">19001</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="k">RUN</span> apt-get update <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    apt-get install android-tools-adb<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="k">WORKDIR</span><span class="w"> </span><span class="s">/app</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="k">COPY</span> package.json yarn.lock app.json ./<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="k">RUN</span> yarn --network-timeout <span class="m">100000</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="k">CMD</span> adb connect <span class="nv">$ADB_IP</span> <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">        yarn run android<span class="err">
</span></span></span></code></pre></div><p><code>FROM node:latest</code></p>
<p>Tells us which Docker Image we are using as a base, in this case, the official node.js image. This is because it
will have a lot of the dependencies we need already installed such as yarn and npm.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">ENV ADB_IP=&#34;192.168.1.1&#34;
</span></span><span class="line"><span class="cl">ENV REACT_NATIVE_PACKAGER_HOSTNAME=&#34;192.255.255.255&#34;
</span></span></code></pre></div><p>Sets an environment variable which can be accessed during runtime of the Docker container. Strictly speaking, these
don&rsquo;t need to be here because we can always inject into the Docker container at runtime, but I like to have the
environment variables documented.</p>
<p>The <strong>ADB_IP</strong> is IP of the Android device 📱 to connect to. The <strong>REACT_NATIVE_PACKAGER_HOSTNAME</strong> environment variable is
very important because it sets which IP address Expo (cli) is running on, this is the IP Address your phone will try to
connect to. If this is not set correctly, you&rsquo;ll get an error similar to Figure 1. You can work out the correct IP
address on Linux by using the following command. The first one should host IP (192.168.27.128 on my machine).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hostname -I
</span></span><span class="line"><span class="cl">192.168.27.128 192.168.130.128 172.17.0.1 172.19.0.1 172.18.0.1
</span></span></code></pre></div><p>The reason this environment variable needs to be set is because by default the React Native packager
(which expo relies on) picks the first IP it sees on the machine, hence you can run expo on your host machine
fine but when you run in a Docker container you cannot connect to it because it&rsquo;s trying to use the Docker
IP address (one of the ones starting with 172.xxx.xxx.xxx).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">EXPOSE 19000
</span></span><span class="line"><span class="cl">EXPOSE 19001
</span></span></code></pre></div><p>This is essentially meta data letting the user of the Docker container know that they can access data on those ports.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">RUN apt-get update <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    apt-get install android-tools-adb
</span></span></code></pre></div><p>Install Android Debugging Bridge (ADB), which is used to connect to an Android device and debug the application.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">COPY package.json yarn.lock app.json ./
</span></span><span class="line"><span class="cl">RUN yarn --network-timeout 100000
</span></span></code></pre></div><p>Copy some important files from host to Docker container. The <code>package.json</code> and <code>yarn.lock</code> are used to install
the dependencies and <code>app.json</code> is required by expo as a bare minimum.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">CMD adb connect $ADB_IP &amp;&amp; \
</span></span><span class="line"><span class="cl">    yarn run android
</span></span><span class="line"><span class="cl">    # runs expo-cli start --android
</span></span></code></pre></div><p><img
        loading="lazy"
        src="/posts/2018-10-31-running-expo-react-native-in-docker/images/error-emulator.png"
        type=""
        alt="Figure 1: Could not connect error 😢"
        
      /></p>
<h2 id="running-docker">Running Docker</h2>
<p>This command runs when the Docker Image is first to run, every other command is used to build to the image itself. This
uses an environment variable passed into the Docker container and connects to the Android device at $ADB<em>IP. Then run
the <strong>android</strong> command in _package.json</em>. Then you can simply run the following commands to build and start your Docker container.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker build -t expo-android .
</span></span><span class="line"><span class="cl">docker run -e <span class="nv">ADB_IP</span><span class="o">=</span>192.168.112.101 <span class="se">\
</span></span></span><span class="line"><span class="cl">            -e <span class="nv">REACT_NATIVE_PACKAGER_HOSTNAME</span><span class="o">=</span>192.168.1.1 <span class="se">\
</span></span></span><span class="line"><span class="cl">            -p 19000:19000 <span class="se">\
</span></span></span><span class="line"><span class="cl">            -p 19001:19001 <span class="se">\
</span></span></span><span class="line"><span class="cl">            expo-android
</span></span></code></pre></div><ul>
<li>-t is used to name the image (expo-android)</li>
<li>. tells Docker where the Dockerfile is (in the current directory)</li>
<li>&ndash;env sets environment used by Docker container when it starts to run (REACT_NATIVE_PACKAGER_HOSTNAME andADB_IP are overwritten using these new values)</li>
<li>-p publishes ports, in this example, it maps port 19000 on the host to port 19000 on the Docker container (and also 19001), as we need to access port 19000 and 19001 so that Expo (expo-cli) can connect to our Android device.</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;3.5&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">expo_android</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">container_name</span><span class="p">:</span><span class="w"> </span><span class="l">expo_android</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">build</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">context</span><span class="p">:</span><span class="w"> </span><span class="l">.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">dockerfile</span><span class="p">:</span><span class="w"> </span><span class="l">Dockerfile</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">env_file</span><span class="p">:</span><span class="w"> </span><span class="l">.env</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="m">19000</span><span class="p">:</span><span class="m">19000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="m">19001</span><span class="p">:</span><span class="m">19001</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">${PWD}/:/app/</span><span class="w">
</span></span></span></code></pre></div><p>Since expo is being used to build mobile phone applications Docker isn&rsquo;t going to be used in production. I prefer to use
docker-compose to do the building and running, it means I can run one simple command and do the building and running in
one step. Quick aside docker-compose is great for development, especially when you need to run multiple Docker container,
but is not really built to be used in production. Look at using a container orchestration tool such as Kubernetes.</p>
<p>I also mount my current directory on the host machine to /app/ directory on the docker container, this is so that any
files that change on my host machine will also change in the Docker container, rather than having to build the
Docker container again.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker-compose up --build -d
</span></span></code></pre></div><h3 id="environment-variables">Environment Variables</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-env" data-lang="env"><span class="line"><span class="cl"><span class="nv">ADB_IP</span><span class="o">=</span><span class="s2">&#34;192.168.112.101&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">REACT_NATIVE_PACKAGER_HOSTNAME</span><span class="o">=</span><span class="s2">&#34;192.168.27.128&#34;</span>
</span></span></code></pre></div><p>An example <code>.env</code> file used to pass environment variables (using docker-compose) to the Docker container.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/hmajid2301/blog/-/tree/main/content/posts/2018-10-31-running-expo-react-native-in-docker/source_code">Example source code</a></li>
<li><a href="https://medium.freecodecamp.org/a-beginner-friendly-introduction-to-containers-vms-and-docker-79a9e3e119b">Docker explained</a></li>
<li><a href="https://github.com/react-community/create-react-native-app/issues/81">GitHub issue around could not connect errors</a></li>
<li><a href="https://www.genymotion.com/">Genymotion emulator</a></li>
<li><a href="https://ezgif.com/overlay">GIF overlay creator (Nyan Docker)</a></li>
<li>React logo from <a href="https://seeklogo.com/vector-logo/273845/react">here</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>Debugging A React Native WebView</title>
      <link>https://haseebmajid.dev/posts/2018-10-27-debugging-a-react-native-webview/</link>
      <pubDate>Sat, 27 Oct 2018 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2018-10-27-debugging-a-react-native-webview/</guid>
      <description>&lt;p&gt;The &lt;em&gt;core&lt;/em&gt; logic of my React Native app involves using WebViews because I need to access the HTML5 canvas. Whilst
developing this code there are bound to be errors and issues with the WebView code. Figuring out how to debug
code within the WebView isn&amp;rsquo;t so obvious.&lt;/p&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2018-10-27-debugging-a-react-native-webview/images/webview-dev-tools.png&#34;
        type=&#34;&#34;
        alt=&#34;Figure 1: Chrome Inspect for the WebView&#34;
        
      /&gt;&lt;/p&gt;
&lt;h2 id=&#34;option-1-chrome-inspect&#34;&gt;Option 1: Chrome Inspect&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Start your Expo/React Native app*.&lt;/li&gt;
&lt;li&gt;Open and chrome and then go to the following URL, &lt;a href=&#34;chrome://inspect&#34;&gt;chrome://inspect&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Then click on the &lt;em&gt;inspect&lt;/em&gt; button, click the top link to open the latest WebView, you should see something similar to Figure 2.&lt;/li&gt;
&lt;li&gt;You should see something similar to Figure 1. Now you explore the WebView like a normal web page.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img
        loading=&#34;lazy&#34;
        src=&#34;../../posts/2018-10-27-debugging-a-react-native-webview/images/chrome-inspect.png&#34;
        type=&#34;&#34;
        alt=&#34;Figure 2: List of WebView&#34;
        
      /&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>The <em>core</em> logic of my React Native app involves using WebViews because I need to access the HTML5 canvas. Whilst
developing this code there are bound to be errors and issues with the WebView code. Figuring out how to debug
code within the WebView isn&rsquo;t so obvious.</p>
<p><img
        loading="lazy"
        src="/posts/2018-10-27-debugging-a-react-native-webview/images/webview-dev-tools.png"
        type=""
        alt="Figure 1: Chrome Inspect for the WebView"
        
      /></p>
<h2 id="option-1-chrome-inspect">Option 1: Chrome Inspect</h2>
<ul>
<li>Start your Expo/React Native app*.</li>
<li>Open and chrome and then go to the following URL, <a href="chrome://inspect">chrome://inspect</a>.</li>
<li>Then click on the <em>inspect</em> button, click the top link to open the latest WebView, you should see something similar to Figure 2.</li>
<li>You should see something similar to Figure 1. Now you explore the WebView like a normal web page.</li>
</ul>
<p><img
        loading="lazy"
        src="/posts/2018-10-27-debugging-a-react-native-webview/images/chrome-inspect.png"
        type=""
        alt="Figure 2: List of WebView"
        
      /></p>
<h2 id="option-2-react-native-debugger">Option 2: React Native Debugger</h2>
<p>Alternatively you can access this page using the React Native Debugger page in chrome.</p>
<ul>
<li>Start your Expo/React Native app*</li>
<li>Go to your React Native debugger on chrome, in my case since I&rsquo;m using Expo my URL is http://192.168.27.128:19001/debugger-ui/</li>
<li>Go to the three dots button (next to close button) &gt; More tools &gt; Remote devices</li>
<li>At the bottom you&rsquo;ll see another panel open up</li>
<li>You should be able to see your Android device in the list</li>
<li>Hit the Inspect button the first item (this will be the latest)</li>
<li>Now you explore the WebView like a normal web page</li>
</ul>
<h2 id="debugging">Debugging</h2>
<p>So to the closest way to debug the WebView I have found is to use console.log statements that will appear in the
DevTools console. In the normal React Native debugger console you won&rsquo;t be able to see any console.log statements
from the WebView. You can only view them by exploring DevTools for Remote devices. As far as I can tell you cannot
use breakpoints in WebViews but still this is better than nothing.</p>
<p><img
        loading="lazy"
        src="/posts/2018-10-27-debugging-a-react-native-webview/images/devtools.gif"
        type=""
        alt="Figure 3: Open DevTools for Remote devices"
        
      /></p>
<h2 id="appendix">Appendix</h2>
<p>Make sure to do this on the same machine/host that is running the emulator. For example, a Genymotion VM is
running on my Windows machine but I can still see it&rsquo;s WebViews on the chrome inspect URL. This can be seen in Figure 3.</p>
<p><img
        loading="lazy"
        src="/posts/2018-10-27-debugging-a-react-native-webview/images/chrome-inspect-emulator.png"
        type=""
        alt="Figure 4: List of WebView"
        
      /></p>
<h3 id="links">Links</h3>
<ul>
<li><a href="https://stackoverflow.com/questions/47711418/debugging-webview-in-react-native-apps?rq=1">With help from this StackOverflow post</a></li>
<li><a href="https://www.genymotion.com/">Genymotion</a></li>
<li>GIFs created with <a href="https://www.screentogif.com/">screentogif</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>React Native/Expo with VirtualBox and Genymotion</title>
      <link>https://haseebmajid.dev/posts/2018-09-03-react-native-expo-with-virtualbox-and-genymotion/</link>
      <pubDate>Mon, 03 Sep 2018 00:00:00 +0000</pubDate>
      <author>Me</author>
      <guid>https://haseebmajid.dev/posts/2018-09-03-react-native-expo-with-virtualbox-and-genymotion/</guid>
      <description>&lt;p&gt;My home PC runs Windows for various conveniences, such as gaming. However, for development, I run an Ubuntu virtual
machine (VM) and Genymotion (on Windows) for testing my app. Genymotion also uses VirtualBox to run its Android
emulators. So we work out how to let two VMs running on the same host communicate with each other
(Ubuntu and Android Emulator).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Please Note:&lt;/strong&gt; This will also work for VMWare Player.&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution&lt;/h2&gt;
&lt;p&gt;There are a few networking options we can choose from when setting up a VM.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>My home PC runs Windows for various conveniences, such as gaming. However, for development, I run an Ubuntu virtual
machine (VM) and Genymotion (on Windows) for testing my app. Genymotion also uses VirtualBox to run its Android
emulators. So we work out how to let two VMs running on the same host communicate with each other
(Ubuntu and Android Emulator).</p>
<p><strong>Please Note:</strong> This will also work for VMWare Player.</p>
<h2 id="solution">Solution</h2>
<p>There are a few networking options we can choose from when setting up a VM.</p>
<ul>
<li>
<p><strong>NAT</strong>: Allows your VMs so communicate with the outside world (outbound network), but your host machine (Windows)has no way to access this network</p>
</li>
<li>
<p><strong>Bridged</strong>: Allows your VMs to access a network using the host computer&rsquo;s Ethernet adapter. However this adds a bit of complexity, as your VM needs it own identity on the network as essentially its treated like another physical machine.</p>
</li>
<li>
<p><strong>Host-only</strong>: Acts a hybrid between the other two options. It allows your VM to communicate with your host machine. So essentially all we need for multiple VMs to communicate with each is other is to turn on Host-only network (on all VMs). This allow them to communicate with the host machine which will act as a &ldquo;bridge&rdquo; (no pun intended).</p>
</li>
</ul>
<p><img
        loading="lazy"
        src="/posts/2018-09-03-react-native-expo-with-virtualbox-and-genymotion/images/network.png"
        type=""
        alt="Network Diagaram"
        
      /></p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li><a href="https://www.virtualbox.org/wiki/Downloads">VirtualBox</a> Installed on the host machine</li>
<li>An <a href="https://docs.expo.io/versions/latest/workflow/create-react-native-app">Expo</a> app in the (Ubuntu) development VM</li>
<li><a href="https://www.genymotion.com/desktop/">Genymotion</a> Installed and setup on the host machine</li>
</ul>
<h2 id="virtualbox">VirtualBox</h2>
<ul>
<li>Open up VirtualBox</li>
<li>Click on the development VM and open the &ldquo;Settings&rdquo;.</li>
<li>Go to &ldquo;Network&rdquo; and Set the following two adapters, as shown in Figure 1</li>
<li>Adapter 1: &ldquo;Host-only Adapter&rdquo;</li>
<li>Adapter 2: &ldquo;NAT&rdquo;</li>
</ul>
<p>NAT allows the Ubuntu VM to use the host machines internet access, it allows it to communicate with the outside world.
The Host-only Adapter allows the Ubuntu VM to communicate with other VM, such as the Genymotion Android emulator.</p>
<p><img
        loading="lazy"
        src="/posts/2018-09-03-react-native-expo-with-virtualbox-and-genymotion/images/ubuntu_network1.png"
        type=""
        alt="Figure 1: Ubuntu VM network settings"
        
      />
<img
        loading="lazy"
        src="/posts/2018-09-03-react-native-expo-with-virtualbox-and-genymotion/images/ubuntu_network2.png"
        type=""
        alt="Figure 1: Ubuntu VM network settings"
        
      /></p>
<h2 id="genymotion">Genymotion</h2>
<p>Genymotion network settings are pretty much the same as the Ubuntu VM, as shown in Figure 2. Please note that the
Host-only adapters can be the same (i.e. #7).</p>
<p><img
        loading="lazy"
        src="/posts/2018-09-03-react-native-expo-with-virtualbox-and-genymotion/images/phone_network1.png"
        type=""
        alt="Figure 2: Android emulator VM network settings"
        
      />
<img
        loading="lazy"
        src="/posts/2018-09-03-react-native-expo-with-virtualbox-and-genymotion/images/phone_network2.png"
        type=""
        alt="Figure 2: Android emulator VM network settings"
        
      /></p>
<h2 id="expo">Expo</h2>
<ul>
<li>Start your Genymotion Android emulator.</li>
<li>Start your Ubuntu VM and open a terminal.</li>
<li>Replace the IP Address with your own one, you can find your IP address on the Android emulator. As shown in Figure 3.</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">adb connect 192.168.112.101
</span></span><span class="line"><span class="cl">exp start
</span></span><span class="line"><span class="cl">exp android
</span></span></code></pre></div><p><img
        loading="lazy"
        src="/posts/2018-09-03-react-native-expo-with-virtualbox-and-genymotion/images/genymotion_ip.png"
        type=""
        alt="Figure 3: Genymotion Android emulator&rsquo;s IP address"
        
      /></p>
<p>That&rsquo;s it you should see your app running on the Genymotion Android emulator now. You can see how to start the
application below in Figure 4.</p>
<p><img
        loading="lazy"
        src="/posts/2018-09-03-react-native-expo-with-virtualbox-and-genymotion/images/connecting.gif"
        type=""
        alt="Figure 4: Starting Expo application on Android emulator"
        
      /></p>
<h2 id="appendix">Appendix</h2>
<ul>
<li>GIFs created with <a href="https://www.screentogif.com/">screentogif</a></li>
<li><a href="http://bertvv.github.io/notes-to-self/2015/09/29/virtualbox-networking-an-overview/">Detailed post about VirtualBox Networking</a></li>
<li>Drawing made with <a href="https://www.draw.io/">draw.io</a></li>
</ul>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
