<?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>React-Hooks on Haseeb Majid</title>
    <link>https://haseebmajid.dev/tags/react-hooks/</link>
    <description>Recent content in React-Hooks on Haseeb Majid</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Sun, 05 Apr 2020 00:00:00 +0000</lastBuildDate><atom:link href="https://haseebmajid.dev/tags/react-hooks/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Using React Hooks, Context &amp; Local Storage</title>
      <link>https://haseebmajid.dev/posts/2020-04-05-using-react-hooks-context-local-storage/</link>
      <pubDate>Sun, 05 Apr 2020 00:00:00 +0000</pubDate>
      
      <guid>https://haseebmajid.dev/posts/2020-04-05-using-react-hooks-context-local-storage/</guid>
      <description>&lt;p&gt;In this article, I will show how you can use React Context with React Hooks to store global state across a React app,
then store that state in local storage. This can be used for example to store light vs dark theme, then whenever the
user visits your website again they will have the same theme they last selected. Which leads to an improved experience.&lt;/p&gt;
&lt;h2 id=&#34;structure&#34;&gt;Structure&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: We will be using typescript&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In this article, I will show how you can use React Context with React Hooks to store global state across a React app,
then store that state in local storage. This can be used for example to store light vs dark theme, then whenever the
user visits your website again they will have the same theme they last selected. Which leads to an improved experience.</p>
<h2 id="structure">Structure</h2>
<blockquote>
<p>Note: We will be using typescript</p>
</blockquote>
<p>We will use a project structure like so:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">.
</span></span><span class="line"><span class="cl">├── src
</span></span><span class="line"><span class="cl">│   ├── App.tsx
</span></span><span class="line"><span class="cl">│   ├── index.html
</span></span><span class="line"><span class="cl">│   ├── index.tsx
</span></span><span class="line"><span class="cl">│   ├── providers
</span></span><span class="line"><span class="cl">│   └── views
</span></span><span class="line"><span class="cl">├── LICENSE
</span></span><span class="line"><span class="cl">├── package.json
</span></span><span class="line"><span class="cl">├── tsconfig.json
</span></span><span class="line"><span class="cl">├── webpack.config.js
</span></span><span class="line"><span class="cl">└── yarn.lock
</span></span></code></pre></div><blockquote>
<p>Note: This application was based on <a href="https://github.com/saltyshiomix/webpack-typescript-react-starter">saltyshiomix&rsquo;s template</a></p>
</blockquote>
<h2 id="getting-started">Getting Started</h2>
<p>Our <code>package.json</code> file looks like this:</p>
<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;name&#34;</span><span class="p">:</span> <span class="s2">&#34;ExampleApp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;1.0.0&#34;</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;start&#34;</span><span class="p">:</span> <span class="s2">&#34;serve dist&#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;react&#34;</span><span class="p">:</span> <span class="s2">&#34;16.9.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;react-dom&#34;</span><span class="p">:</span> <span class="s2">&#34;16.9.0&#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;devdependencies&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;typescript&#34;</span><span class="p">:</span> <span class="s2">&#34;3.6.2&#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 example application linked will also be using babel for transpiling our code to Javascript
and Webpack for bundling our code into a single <code>index.js</code> file.</p>
<h2 id="app">App</h2>
<p>Now onto how we can use React Hooks to persist user settings in local storage. So every time they
visit our website it will &ldquo;restore&rdquo; their previous setting, such as theme, light or dark.</p>
<h3 id="darkmodeprovidertsx">DarkModeProvider.tsx</h3>
<p>React Contexts can be used to store the global state of our application. Such as our current theme, this can then be
accessed anywhere in our application and also changed anywhere. React contexts provide us with two &ldquo;sub-components&rdquo;, a
provider and, a consumer for that specific React context.</p>
<ul>
<li>Provider: The component that will provide the value of the context (stored)</li>
<li>Consumer: The component that will consume the value</li>
</ul>
<blockquote>
<p>Context provides a way to pass data through the component tree without having to pass props down manually at every level. - <a href="https://reactjs.org/docs/context.html">https://reactjs.org/docs/context.html</a></p>
</blockquote>
<p>React hooks allow us to access the React context from within functional components. In our case, it means we don&rsquo;t have
to use the React context&rsquo;s consumer we can use React hooks instead to use the context, this can be seen in the <code>MainApp.tsx</code></p>
<p>First, let&rsquo;s create our React context that will store the current theme the user has selected. It will also
give us a function that other components can use to update the theme. Finally, after any change has been made
it will update the local storage with the users latest settings.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><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">Context</span><span class="p">,</span> <span class="nx">createContext</span><span class="p">,</span> <span class="nx">useReducer</span><span class="p">,</span> <span class="nx">useEffect</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;react&#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="kr">const</span> <span class="nx">LIGHT_THEME</span>: <span class="kt">Theme</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">background</span><span class="o">:</span> <span class="s2">&#34;#fafafa&#34;</span> <span class="kr">as</span> <span class="nx">BackgroundColors</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">color</span><span class="o">:</span> <span class="s2">&#34;#000000&#34;</span> <span class="kr">as</span> <span class="nx">ForegroundColors</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">isDark</span>: <span class="kt">false</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="kr">const</span> <span class="nx">DARK_THEME</span>: <span class="kt">Theme</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">background</span><span class="o">:</span> <span class="s2">&#34;#333333&#34;</span> <span class="kr">as</span> <span class="nx">BackgroundColors</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">color</span><span class="o">:</span> <span class="s2">&#34;#fafafa&#34;</span> <span class="kr">as</span> <span class="nx">ForegroundColors</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">isDark</span>: <span class="kt">true</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="kr">type</span> <span class="nx">BackgroundColors</span> <span class="o">=</span> <span class="s2">&#34;#333333&#34;</span> <span class="o">|</span> <span class="s2">&#34;#fafafa&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">type</span> <span class="nx">ForegroundColors</span> <span class="o">=</span> <span class="s2">&#34;#000000&#34;</span> <span class="o">|</span> <span class="s2">&#34;#fafafa&#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="kr">interface</span> <span class="nx">Theme</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">background</span>: <span class="kt">BackgroundColors</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">color</span>: <span class="kt">ForegroundColors</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">isDark</span>: <span class="kt">boolean</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">interface</span> <span class="nx">DarkModeContext</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">mode</span>: <span class="kt">Theme</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">dispatch</span>: <span class="kt">React.Dispatch</span><span class="p">&lt;</span><span class="nt">any</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">const</span> <span class="nx">darkModeReducer</span> <span class="o">=</span> <span class="p">(</span><span class="nx">_</span>: <span class="kt">any</span><span class="p">,</span> <span class="nx">isDark</span>: <span class="kt">boolean</span><span class="p">)</span> <span class="o">=&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">isDark</span> <span class="o">?</span> <span class="nx">DARK_THEME</span> : <span class="kt">LIGHT_THEME</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">DarkModeContext</span>: <span class="kt">Context</span><span class="p">&lt;</span><span class="nt">DarkModeContext</span><span class="p">&gt;</span> <span class="o">=</span> <span class="nx">createContext</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="p">{}</span> <span class="kr">as</span> <span class="nx">DarkModeContext</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">initialState</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s2">&#34;DarkMode&#34;</span><span class="p">)</span> <span class="kr">as</span> <span class="kt">string</span><span class="p">)</span> <span class="o">||</span> <span class="nx">LIGHT_THEME</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">DarkModeProvider</span>: <span class="kt">React.FC</span> <span class="o">=</span> <span class="p">({</span> <span class="nx">children</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">[</span><span class="nx">mode</span><span class="p">,</span> <span class="nx">dispatch</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useReducer</span><span class="p">(</span><span class="nx">darkModeReducer</span><span class="p">,</span> <span class="nx">initialState</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s2">&#34;DarkMode&#34;</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">mode</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="p">[</span><span class="nx">mode</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">
</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">DarkModeContext.Provider</span>
</span></span><span class="line"><span class="cl">      <span class="na">value</span><span class="o">=</span><span class="p">{{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">mode</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">dispatch</span>
</span></span><span class="line"><span class="cl">      <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">{</span><span class="nx">children</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">DarkModeContext.Provider</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></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="p">{</span> <span class="nx">DarkModeProvider</span><span class="p">,</span> <span class="nx">DarkModeContext</span> <span class="p">};</span>
</span></span></code></pre></div><p>Next, we will import all of the modules we will need to use then. We will define our two different themes <code>LIGHT_THEME</code>
and <code>DARK_THEME</code>. Then finally because we are using Typescript we will define types for the Themes and the context we
will use.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">darkModeReducer</span> <span class="o">=</span> <span class="p">(</span><span class="nx">_</span>: <span class="kt">any</span><span class="p">,</span> <span class="nx">isDark</span>: <span class="kt">boolean</span><span class="p">)</span> <span class="o">=&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">isDark</span> <span class="o">?</span> <span class="nx">DARK_THEME</span> : <span class="kt">LIGHT_THEME</span><span class="p">;</span>
</span></span></code></pre></div><p>Next, we will define a reducer. A reducer is a pure function which does not use the state of the
current app so it cannot have any unintended side-effects. Exactly the same functions we
would define if we were using Redux. In this case, the reducer just returns the <code>DARK_THEME</code>
if the <code>isDark</code> argument is <code>true</code> else it returns the <code>LIGHT_THEME</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">DarkModeContext</span>: <span class="kt">Context</span><span class="p">&lt;</span><span class="nt">DarkModeContext</span><span class="p">&gt;</span> <span class="o">=</span> <span class="nx">createContext</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="p">{}</span> <span class="kr">as</span> <span class="nx">DarkModeContext</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">initialState</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s2">&#34;DarkMode&#34;</span><span class="p">)</span> <span class="kr">as</span> <span class="kt">string</span><span class="p">)</span> <span class="o">||</span> <span class="nx">LIGHT_THEME</span><span class="p">;</span>
</span></span></code></pre></div><p>After this, we create our React context called <code>DarkModeContext</code> and we give it a default empty object
(we don&rsquo;t really mind too much). We then define the default value. It tries to check the value
stored in <code>localstorage</code>. If there is none, then we use the <code>LIGHT_THEME</code>. After which we define the provider.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">DarkModeProvider</span>: <span class="kt">React.FC</span> <span class="o">=</span> <span class="p">({</span> <span class="nx">children</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">[</span><span class="nx">mode</span><span class="p">,</span> <span class="nx">dispatch</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useReducer</span><span class="p">(</span><span class="nx">darkModeReducer</span><span class="p">,</span> <span class="nx">initialState</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s2">&#34;DarkMode&#34;</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">mode</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span> <span class="p">[</span><span class="nx">mode</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">
</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">DarkModeContext.Provider</span>
</span></span><span class="line"><span class="cl">      <span class="na">value</span><span class="o">=</span><span class="p">{{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">mode</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">dispatch</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">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span><span class="nx">children</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">DarkModeContext.Provider</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></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="p">{</span> <span class="nx">DarkModeProvider</span><span class="p">,</span> <span class="nx">DarkModeContext</span> <span class="p">};</span>
</span></span></code></pre></div><p>The provider is what is used to give other components access to the context. Here you can see
we use the <code>useReducer</code> hook and give it our <code>darkModeReducer</code> with the initial value. This
reducer will then return a <code>mode</code> which is the current theme data and a function <code>dispatch</code>
which will be used to update the current theme. Breaking it down a bit further we see:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s2">&#34;DarkMode&#34;</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">mode</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">},</span> <span class="p">[</span><span class="nx">mode</span><span class="p">]);</span>
</span></span></code></pre></div><p>Next, we define the <code>useEffect</code> hook which is called every time the <code>mode</code> is changed, by the
<code>dispatch</code> function being called. Hence the we have the <code>[mode]</code> at the end. It very simply
stores the current theme into the user&rsquo;s local storage under the key <code>DarkMode</code>. Now if
this was changed from light -&gt; dark and then the user comes back to the site, the initial value
we would get from <code>localstorage.getItem(&quot;DarkMode&quot;)</code> would not, of course, be the dark theme.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><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">DarkModeContext.Provider</span>
</span></span><span class="line"><span class="cl">    <span class="na">value</span><span class="o">=</span><span class="p">{{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">mode</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">dispatch</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">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span><span class="nx">children</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">DarkModeContext.Provider</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="c1">//...
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">export</span> <span class="p">{</span> <span class="nx">DarkModeProvider</span><span class="p">,</span> <span class="nx">DarkModeContext</span> <span class="p">};</span>
</span></span></code></pre></div><p>Finally, we create the Provider component we will export, the <code>mode</code> is the theme data that other
components can use and <code>dispatch</code> is the function other components can use to change the current
theme. As long as they are a child of the <code>DarkModeProvider</code> hence the <code>{children}</code> which will be a prop.</p>
<h3 id="app-1">App</h3>
<p>Our &ldquo;Main&rdquo; app page we will import the Provider that will export from our providers folder.
This means any component that is a child of this will be able to access and update the current
theme, we will see how to do that later on.</p>
<blockquote>
<p>Warning: The provider needs to be in a separate component to those that access the React Hook. Hence we import the <code>MainApp</code> component rather than including all of the <code>MainApp.tsx</code> in <code>App.tsx</code>.</p>
</blockquote>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">React</span> <span class="kr">from</span> <span class="s2">&#34;react&#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="p">{</span> <span class="nx">DarkModeProvider</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;~/providers/DarkModeProvider&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">MainApp</span> <span class="kr">from</span> <span class="s2">&#34;~/views/MainApp&#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">App</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</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">DarkModeProvider</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">MainApp</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">DarkModeProvider</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></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">App</span><span class="p">;</span>
</span></span></code></pre></div><blockquote>
<p>Note: The module resolver allows us to refer to src/ folder as ~ in our imports. I wrote a whole article about how you can use it <a href="/blog/better-imports-with-babel-tspath/">here</a> (#ShamelessPlug)</p>
</blockquote>
<p>Now the MainApp is a very basic page: it contains a single button which is used to toggle our theme
for dark to light and vice versa. Here we use React hooks with React context to be able to update and retrieve
the theme.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><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">useContext</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;react&#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="p">{</span> <span class="nx">DarkModeContext</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;~/providers/DarkModeProvider&#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">MainApp</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">theme</span> <span class="o">=</span> <span class="nx">useContext</span><span class="p">(</span><span class="nx">DarkModeContext</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">{</span> <span class="nx">background</span><span class="p">,</span> <span class="nx">color</span><span class="p">,</span> <span class="nx">isDark</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">theme</span><span class="p">.</span><span class="nx">mode</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</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">div</span>
</span></span><span class="line"><span class="cl">      <span class="na">style</span><span class="o">=</span><span class="p">{{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">background</span>: <span class="kt">background</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">color</span>: <span class="kt">color</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">minHeight</span><span class="o">:</span> <span class="s2">&#34;100vh&#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">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span><span class="nx">Theme</span> <span class="k">is</span> <span class="p">{</span><span class="nx">isDark</span> <span class="o">?</span> <span class="s2">&#34;Dark&#34;</span> <span class="o">:</span> <span class="s2">&#34;Light&#34;</span><span class="p">}&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">button</span> <span class="na">onClick</span><span class="o">=</span><span class="p">{()</span> <span class="o">=&gt;</span> <span class="nx">setTheme</span><span class="p">(</span><span class="nx">theme</span><span class="p">)}&gt;</span><span class="nx">Change</span> <span class="nx">Theme</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">div</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></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">setTheme</span> <span class="o">=</span> <span class="p">(</span><span class="nx">darkMode</span>: <span class="kt">DarkModeContext</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">isDark</span> <span class="o">=</span> <span class="nx">darkMode</span><span class="p">.</span><span class="nx">mode</span><span class="p">.</span><span class="nx">isDark</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">darkMode</span><span class="p">.</span><span class="nx">dispatch</span><span class="p">(</span><span class="o">!</span><span class="nx">isDark</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">MainApp</span><span class="p">;</span>
</span></span></code></pre></div><h4 id="usecontext">useContext</h4>
<p>The <code>useContext</code> is an example of a React Hook. It allows users to access a specific context from with a functional
component, a component which is not a class. The context has a mode property which stores the current theme we should
display light or dark. Such as <code>background</code> and <code>color</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">theme</span> <span class="o">=</span> <span class="nx">useContext</span><span class="p">(</span><span class="nx">DarkModeContext</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">background</span><span class="p">,</span> <span class="nx">color</span><span class="p">,</span> <span class="nx">isDark</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">theme</span><span class="p">.</span><span class="nx">mode</span><span class="p">;</span>
</span></span></code></pre></div><p>This is then used in our &ldquo;CSS&rdquo; styling to style the page background and button colour. We also show the current theme
that is set on the page.</p>
<h4 id="change-theme">Change Theme</h4>
<p>So we can access the data from our React context but how do we change the theme? Well, we use the button, which
has an <code>onClick</code> event. The <code>setTheme</code> function gets the current theme from the <code>isDark</code> property of the context.
It then calls the <code>dispatch</code> function we have defined in the context to change to the theme to the opposite
it is at the moment. So light theme -&gt; dark theme and dark theme -&gt; light theme.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">button</span> <span class="na">onClick</span><span class="o">=</span><span class="p">{()</span> <span class="o">=&gt;</span> <span class="nx">setTheme</span><span class="p">(</span><span class="nx">theme</span><span class="p">)}&gt;</span><span class="nx">Change</span> <span class="nx">Theme</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">//...
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">setTheme</span> <span class="o">=</span> <span class="p">(</span><span class="nx">darkMode</span>: <span class="kt">DarkModeContext</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">isDark</span> <span class="o">=</span> <span class="nx">darkMode</span><span class="p">.</span><span class="nx">mode</span><span class="p">.</span><span class="nx">isDark</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">darkMode</span><span class="p">.</span><span class="nx">dispatch</span><span class="p">(</span><span class="o">!</span><span class="nx">isDark</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>That&rsquo;s it! We successfully created a very simple React app that leverage React hooks and React context to allow us
to store the user&rsquo;s settings into local storage so it can persist and the user will be able to use the same settings
they set last time, such as dark mode instead of the light mode.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/hmajid2301/blog/-/tree/main/content/posts/2020-04-05-using-react-hooks-context-local-storage/source_code">Example source code</a></li>
<li>Photo by <a href="https://unsplash.com/@cristianpalmer">Cristian Palmer</a> on Unsplash</li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>Auto Toggle Dark Theme on your React Native App</title>
      <link>https://haseebmajid.dev/posts/2020-01-25-auto-toggle-dark-theme-on-your-react-native-app/</link>
      <pubDate>Sat, 25 Jan 2020 00:00:00 +0000</pubDate>
      
      <guid>https://haseebmajid.dev/posts/2020-01-25-auto-toggle-dark-theme-on-your-react-native-app/</guid>
      <description>&lt;p&gt;In this article, I will show you how you can change the theme of your app depending on
the time of the day. We will change the theme of the app depending on if the sun has set or risen.&lt;/p&gt;
&lt;h2 id=&#34;our-application&#34;&gt;Our Application&lt;/h2&gt;
&lt;p&gt;To get started we will create a new React Native app by running the following command,
&lt;code&gt;react-native init ExampleApp --template typescript&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: We are using path aliases so &lt;code&gt;~&lt;/code&gt; is the same as saying &lt;code&gt;src/&lt;/code&gt;, this keeps the
import paths cleaner. More information &lt;a href=&#34;https://haseebmajid.dev/posts/2019-12-01-better-imports-with-typescript-aliases-babel-and-tspath/&#34;&gt;here&lt;/a&gt; #ShamelessPlug.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In this article, I will show you how you can change the theme of your app depending on
the time of the day. We will change the theme of the app depending on if the sun has set or risen.</p>
<h2 id="our-application">Our Application</h2>
<p>To get started we will create a new React Native app by running the following command,
<code>react-native init ExampleApp --template typescript</code>.</p>
<p><em>Note</em>: We are using path aliases so <code>~</code> is the same as saying <code>src/</code>, this keeps the
import paths cleaner. More information <a href="/posts/2019-12-01-better-imports-with-typescript-aliases-babel-and-tspath/">here</a> #ShamelessPlug.</p>
<h3 id="auto-theme">Auto Theme</h3>
<p>First, let&rsquo;s create the module which will contain the core logic for this app.
This module will be used to determine if we should toggle the dark theme on or off.
It does this by using the user&rsquo;s current location, using the
<a href="https://github.com/timfpark/react-native-location">react-native-location</a> library.
Then working out the sunrise and sunset at that location, using <a href="https://github.com/udivankin/sunrise-sunset">sunrise-sunset-js</a>.</p>
<p>However, we will only check the location once per day, we store the latitude and longitude locally
on the device and if it within a day since it was set, then we use these locally stored values.
However if the stored values are older than a day then we find the new latitude and longitude,
use those and replace the old values with these new values.</p>
<p>The AutoTheme is a class, let&rsquo;s take a look at the main function of the class</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kr">class</span> <span class="nx">AutoTheme</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">private</span> <span class="kr">static</span> <span class="nx">oneDay</span> <span class="o">=</span> <span class="mi">24</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kr">public</span> <span class="kr">async</span> <span class="nx">shouldToggleDarkTheme() {</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">currentTime</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="p">{</span> <span class="nx">sunrise</span><span class="p">,</span> <span class="nx">sunset</span> <span class="p">}</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">getSunriseAndSunsetTime</span><span class="p">(</span><span class="nx">currentTime</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">toggleTheme</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">sunrise</span> <span class="o">!==</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="nx">sunset</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="p">(</span><span class="nx">currentTime</span> <span class="o">&gt;</span> <span class="nx">sunrise</span> <span class="o">&amp;&amp;</span> <span class="nx">currentTime</span> <span class="o">&lt;</span> <span class="nx">sunset</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">toggleTheme</span> <span class="o">=</span> <span class="kc">false</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="k">return</span> <span class="nx">toggleTheme</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="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span></code></pre></div><p>The logic is fairly simple</p>
<ul>
<li>Get the current time</li>
<li>Get the time the sun will rise/set</li>
<li>If the current time is between sunrise and sunset
<ul>
<li>then leave the theme light (return false, i.e. don&rsquo;t toggle the theme to dark)</li>
</ul>
</li>
<li>else
<ul>
<li>toggle the theme to dark</li>
</ul>
</li>
</ul>
<p>In the example below, we would toggle the dark theme on because the sun has already set for that day.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">currentTime = 5.48pm
</span></span><span class="line"><span class="cl">sunrise = 6.30am
</span></span><span class="line"><span class="cl">sunset = 4.45pm
</span></span></code></pre></div><p>So how do we get the sunrise/sunset time ? First, we need to get the latitude and longitude.
Then using the latitude and longitude we work out the sunset and sunrise times (for the current day).
Sometimes with the sunset-sunrise library, it will show you the sunrise for the next day.
If this is the case we simply remove a day from the sunrise date, so we&rsquo;re always
comparing the sunrise/sunset and current time on the same day.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl">  <span class="kr">private</span> <span class="kr">async</span> <span class="nx">getSunriseAndSunsetTime</span><span class="p">(</span><span class="nx">currentTime</span>: <span class="kt">Date</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="p">{</span><span class="nx">latitude</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">}</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">getLatitudeLongitude</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">sunrise</span> <span class="o">=</span> <span class="nx">getSunrise</span><span class="p">(</span><span class="nx">latitude</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">,</span> <span class="nx">currentTime</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">sunset</span> <span class="o">=</span> <span class="nx">getSunset</span><span class="p">(</span><span class="nx">latitude</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">,</span> <span class="nx">currentTime</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">sunrise</span> <span class="o">&gt;</span> <span class="nx">sunset</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">sunrise</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="nx">sunset</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span> <span class="o">-</span> <span class="nx">AutoTheme</span><span class="p">.</span><span class="nx">oneDay</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">return</span> <span class="p">{</span><span class="nx">sunset</span><span class="p">,</span> <span class="nx">sunrise</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span></code></pre></div><p>As stated above we get the latitude-longitude data either from local storage (async storage),
or we get completely new latitude-longitude data from the users&rsquo;s current location.
We check if the stored location is older than a day and if it is we get the user&rsquo;s current location.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl">  <span class="kr">private</span> <span class="kr">async</span> <span class="nx">getLatitudeLongitude() {</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">currentDate</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">lastQueried</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">AsyncStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">&#39;@LastQueriedLocation&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">latitude</span>: <span class="kt">number</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">longitude</span>: <span class="kt">number</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">lastQueriedDate</span>: <span class="kt">Date</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">lastQueried</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">lastQueriedDate</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="nx">lastQueried</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">lastQueriedDate</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="nx">currentDate</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span> <span class="o">-</span> <span class="nx">AutoTheme</span><span class="p">.</span><span class="nx">oneDay</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="k">if</span> <span class="p">(</span><span class="nx">currentDate</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span> <span class="o">-</span> <span class="nx">lastQueriedDate</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="nx">AutoTheme</span><span class="p">.</span><span class="nx">oneDay</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="p">({</span><span class="nx">latitude</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">}</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">getNewLatitudeLongitude</span><span class="p">(</span><span class="nx">currentDate</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">latitude</span> <span class="o">=</span> <span class="nb">Number</span><span class="p">(</span><span class="k">await</span> <span class="nx">AsyncStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">&#39;@Latitude&#39;</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">      <span class="nx">longitude</span> <span class="o">=</span> <span class="nb">Number</span><span class="p">(</span><span class="k">await</span> <span class="nx">AsyncStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="s1">&#39;@Longitude&#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 class="k">return</span> <span class="p">{</span><span class="nx">latitude</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span></code></pre></div><p>The final function is used to get the user&rsquo;s current location (latitude and longitude), we then store this
current location in local storage (async storage), alongside the current date. This date is used to check
later on if we need to get the user&rsquo;s location again.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl">  <span class="kr">private</span> <span class="kr">async</span> <span class="nx">getNewLatitudeLongitude</span><span class="p">(</span><span class="nx">currentDate</span>: <span class="kt">Date</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">latitude</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">longitude</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">granted</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">RNLocation</span><span class="p">.</span><span class="nx">requestPermission</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">      <span class="nx">ios</span><span class="o">:</span> <span class="s1">&#39;whenInUse&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">android</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">detail</span><span class="o">:</span> <span class="s1">&#39;coarse&#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 class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">granted</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kd">let</span> <span class="nx">location</span>: <span class="kt">Location</span> <span class="o">|</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">location</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">RNLocation</span><span class="p">.</span><span class="nx">getLatestLocation</span><span class="p">({</span><span class="nx">timeout</span>: <span class="kt">60000</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span> <span class="k">catch</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">Snackbar</span><span class="p">.</span><span class="nx">show</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">          <span class="nx">title</span><span class="o">:</span> <span class="s1">&#39;Failed to get location, please check it is turned on&#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 class="k">throw</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;No location found&#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 class="k">if</span> <span class="p">(</span><span class="nx">location</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">latitude</span> <span class="o">=</span> <span class="nx">location</span><span class="p">.</span><span class="nx">latitude</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nx">longitude</span> <span class="o">=</span> <span class="nx">location</span><span class="p">.</span><span class="nx">longitude</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">await</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">          <span class="nx">AsyncStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s1">&#39;@Latitude&#39;</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">latitude</span><span class="p">)),</span>
</span></span><span class="line"><span class="cl">          <span class="nx">AsyncStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="s1">&#39;@Longitude&#39;</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">longitude</span><span class="p">)),</span>
</span></span><span class="line"><span class="cl">          <span class="nx">AsyncStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;@LastQueriedLocation&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">currentDate</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></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">latitude</span> <span class="o">===</span> <span class="kc">undefined</span> <span class="o">||</span> <span class="nx">longitude</span> <span class="o">===</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">throw</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;No location found&#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 class="k">return</span> <span class="p">{</span><span class="nx">latitude</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span></code></pre></div><h3 id="theme-context">Theme Context</h3>
<p>Next, let&rsquo;s take a look at the module in charge of actually changing our theme and storing the current
theme (used by the other components). We will use React&rsquo;s Context, React Contexts can be used to store the
global state of our application. Such as our current theme, this can then be accessed anywhere in our
application and also changed anywhere.</p>
<blockquote>
<p>Context provides a way to pass data through the component tree without having to pass props down manually at every level. - <a href="https://reactjs.org/docs/context.html">https://reactjs.org/docs/context.html</a></p>
</blockquote>
<p>In our case, we don&rsquo;t want to have to pass the Theme to every component as a prop. So we store it in our a React
context. Firstly, we define some types that will be used in our React context file, such as the light and
dark theme constants.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><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">Context</span><span class="p">,</span> <span class="nx">createContext</span><span class="p">,</span> <span class="nx">useState</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;react&#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">type</span> <span class="nx">ThemeColors</span> <span class="o">=</span> <span class="s2">&#34;#17212D&#34;</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></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">ITheme</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">background</span>: <span class="kt">ThemeColors</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">color</span>: <span class="kt">ThemeColors</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">isDark</span>: <span class="kt">boolean</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">LIGHT_THEME</span>: <span class="kt">ITheme</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">background</span><span class="o">:</span> <span class="s2">&#34;#FFF&#34;</span> <span class="kr">as</span> <span class="nx">ThemeColors</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">color</span><span class="o">:</span> <span class="s2">&#34;#17212D&#34;</span> <span class="kr">as</span> <span class="nx">ThemeColors</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">isDark</span>: <span class="kt">false</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">DARK_THEME</span>: <span class="kt">ITheme</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">background</span><span class="o">:</span> <span class="s2">&#34;#17212D&#34;</span> <span class="kr">as</span> <span class="nx">ThemeColors</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">color</span><span class="o">:</span> <span class="s2">&#34;#FFF&#34;</span> <span class="kr">as</span> <span class="nx">ThemeColors</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">isDark</span>: <span class="kt">true</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">interface</span> <span class="nx">IThemeContext</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">theme</span>: <span class="kt">ITheme</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">changeTheme</span><span class="o">:</span> <span class="p">(</span><span class="nx">isDark</span>: <span class="kt">boolean</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="k">void</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Next, we create our context with some default values. This then allows us to access the provider
and consumer (<code>ThemeContext.Provider</code>);</p>
<ul>
<li>Provider: The component that will provide the value of the context (stored).</li>
<li>Consumer: The component that will consume the value</li>
</ul>
<p><em>Note</em>: We will not use the consumer part in our app because we are accessing the value
in other ways (React hooks).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ts" data-lang="ts"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">ThemeContext</span>: <span class="kt">Context</span><span class="p">&lt;</span><span class="nt">IThemeContext</span><span class="p">&gt;</span> <span class="o">=</span> <span class="nx">createContext</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">changeTheme</span><span class="o">:</span> <span class="p">(</span><span class="nx">_</span>: <span class="kt">boolean</span><span class="p">)</span> <span class="o">=&gt;</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">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">theme</span>: <span class="kt">LIGHT_THEME</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now let&rsquo;s define our provider.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">ThemeProvider</span>: <span class="kt">React.FC</span> <span class="o">=</span> <span class="p">({</span> <span class="nx">children</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">[</span><span class="nx">themeState</span><span class="p">,</span> <span class="nx">setTheme</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">theme</span>: <span class="kt">LIGHT_THEME</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">changeTheme</span> <span class="o">=</span> <span class="p">(</span><span class="nx">isDark</span>: <span class="kt">boolean</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">setTheme</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">      <span class="nx">theme</span>: <span class="kt">isDark</span> <span class="o">?</span> <span class="nx">DARK_THEME</span> : <span class="kt">LIGHT_THEME</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="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">ThemeContext.Provider</span>
</span></span><span class="line"><span class="cl">      <span class="na">value</span><span class="o">=</span><span class="p">{{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">changeTheme</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">theme</span>: <span class="kt">themeState.theme</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">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span><span class="nx">children</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">ThemeContext.Provider</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></code></pre></div><p>The <code>useState</code> function is a React hook, which returns the current state <code>themeState</code> and function
to change the state <code>setTheme</code>, in this case, we can pass theme (light theme as default) so that the state
can only be a theme object, cannot change it to say 0.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="kr">const</span> <span class="p">[</span><span class="nx">themeState</span><span class="p">,</span> <span class="nx">setTheme</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">theme</span>: <span class="kt">LIGHT_THEME</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Then we define the function that can change our theme, if <code>isDark</code> is <code>true</code> then the
theme becomes dark else it becomes light.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">changeTheme</span> <span class="o">=</span> <span class="p">(</span><span class="nx">isDark</span>: <span class="kt">boolean</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">setTheme</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">theme</span>: <span class="kt">isDark</span> <span class="o">?</span> <span class="nx">DARK_THEME</span> : <span class="kt">LIGHT_THEME</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><p>Finally, we define the actual component for theme provider, it takes in any React component. This way any component
surronded by the provider can access/change the app theme.
We need to give the provider a function to change the value and the value itself.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><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">ThemeContext.Provider</span>
</span></span><span class="line"><span class="cl">    <span class="na">value</span><span class="o">=</span><span class="p">{{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">changeTheme</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">theme</span>: <span class="kt">themeState.theme</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">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span><span class="nx">children</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">ThemeContext.Provider</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span></code></pre></div><h3 id="app">App</h3>
<p>We use our provider in the main function</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">React</span> <span class="kr">from</span> <span class="s2">&#34;react&#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="p">{</span> <span class="nx">ThemeProvider</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;~/providers/ThemeContext&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">MainApp</span> <span class="kr">from</span> <span class="s2">&#34;~/MainApp&#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">App</span> <span class="kr">extends</span> <span class="nx">React</span><span class="p">.</span><span class="nx">Component</span><span class="o">&lt;</span><span class="p">{},</span> <span class="p">{}</span><span class="o">&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">public</span> <span class="nx">render() {</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">ThemeProvider</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">MainApp</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;/</span><span class="nt">ThemeProvider</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><h3 id="main-app">Main App</h3>
<p>Now we have the logic to determine if we should change to a dark theme, depending on the time of day.
But how/when do we call this auto theme module, well this is done through the <code>MainApp.tsx</code> module.
Below is a very simple page, with a logo (that changes depending on the theme) a switch
to turn on auto-theme and the current theme displayed i.e. light or dark.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl">  <span class="c1">// Access Theme context within this React class.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="kr">public</span> <span class="kr">static</span> <span class="nx">contextType</span> <span class="o">=</span> <span class="nx">ThemeContext</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="kr">public</span> <span class="nx">context</span><span class="o">!:</span> <span class="nx">React</span><span class="p">.</span><span class="nx">ContextType</span><span class="p">&lt;</span><span class="nt">typeof</span> <span class="na">ThemeContext</span><span class="p">&gt;;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// Set default state for the class.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="kr">public</span> <span class="nx">state</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">autoTheme</span>: <span class="kt">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">autoToggleTheme</span>: <span class="kt">new</span> <span class="nx">AutoTheme</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">public</span> <span class="nx">render() {</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">theme</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">context</span><span class="p">.</span><span class="nx">theme</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="kt">1</span><span class="p">,</span> <span class="nx">backgroundColor</span>: <span class="kt">theme.background</span><span class="p">}}&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">Header</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="nt">ListItem</span>
</span></span><span class="line"><span class="cl">          <span class="na">containerStyle</span><span class="o">=</span><span class="p">{{</span>
</span></span><span class="line"><span class="cl">            <span class="nx">backgroundColor</span>: <span class="kt">theme.background</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="na">topDivider</span><span class="o">=</span><span class="p">{</span><span class="kc">true</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="na">bottomDivider</span><span class="o">=</span><span class="p">{</span><span class="kc">true</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="na">titleStyle</span><span class="o">=</span><span class="p">{{</span><span class="nx">color</span>: <span class="kt">theme.color</span><span class="p">}}</span>
</span></span><span class="line"><span class="cl">          <span class="na">title</span><span class="o">=</span><span class="s">&#34;Auto Toggle Dark Theme&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="na">switch</span><span class="o">=</span><span class="p">{{</span>
</span></span><span class="line"><span class="cl">            <span class="nx">onValueChange</span>: <span class="kt">this.autoTheme.bind</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">autoTheme</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">            <span class="nx">thumbColor</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">trackColor</span><span class="o">:</span> <span class="p">{</span><span class="kc">false</span><span class="o">:</span> <span class="s1">&#39;gray&#39;</span><span class="p">,</span> <span class="kc">true</span><span class="o">:</span> <span class="s1">&#39;blue&#39;</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">            <span class="nx">value</span>: <span class="kt">this.state.autoTheme</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">/&gt;</span>
</span></span><span class="line"><span class="cl">
</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="kt">1</span><span class="p">,</span> <span class="nx">justifyContent</span><span class="o">:</span> <span class="s1">&#39;center&#39;</span><span class="p">,</span> <span class="nx">alignItems</span><span class="o">:</span> <span class="s1">&#39;center&#39;</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="na">style</span><span class="o">=</span><span class="p">{{</span><span class="nx">color</span>: <span class="kt">theme.color</span><span class="p">,</span> <span class="nx">fontSize</span>: <span class="kt">30</span><span class="p">}}&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="nx">Current</span> <span class="nx">Theme</span><span class="o">:</span> <span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">context</span><span class="p">.</span><span class="nx">theme</span><span class="p">.</span><span class="nx">isDark</span> <span class="o">?</span> <span class="s1">&#39;Dark&#39;</span> <span class="o">:</span> <span class="s1">&#39;Light&#39;</span><span class="p">}</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></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">&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></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span></code></pre></div><p><img
        loading="lazy"
        src="/posts/2020-01-25-auto-toggle-dark-theme-on-your-react-native-app/images/main.png"
        type=""
        alt="Main Page"
        
      /></p>
<p>The theme is changed using the line <code>this.context.changeTheme(isDark);</code> essentially sets the theme for the app.
We can then do something like <code>this.context.theme.color</code> to get the current colour or
<code>this.context.theme.background</code> to get the background colour the app should be using.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl">  <span class="c1">// Called when the switch is toggled
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="kr">private</span> <span class="nx">autoTheme</span> <span class="o">=</span> <span class="kr">async</span> <span class="p">(</span><span class="nx">value</span>: <span class="kt">boolean</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">autoTheme</span>: <span class="kt">value</span><span class="p">});</span>
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">isDark</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">isDark</span> <span class="o">=</span> <span class="k">await</span> <span class="k">new</span> <span class="nx">AutoTheme</span><span class="p">().</span><span class="nx">shouldToggleDarkTheme</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="k">this</span><span class="p">.</span><span class="nx">context</span><span class="p">.</span><span class="nx">changeTheme</span><span class="p">(</span><span class="nx">isDark</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">// ...
</span></span></span></code></pre></div><p>The other key function is this one, where we listen for when the app goes from background
to the foreground, if this happens we then call the auto theme module and check if we should
toggle the theme, say you do this between sunsets. You background the app at 6.58 PM, the
sunsets at 7.0 2PM and you foreground the app at 7.04 PM then when the user returns
<code>this.context.changeTheme(true)</code> will be called like this (true) and then the values
returned by <code>this.context.theme</code> would change to the dark theme.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{...,</span> <span class="nx">AppState</span><span class="p">}</span> <span class="kr">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">public</span> <span class="kr">async</span> <span class="nx">componentDidMount() {</span>
</span></span><span class="line"><span class="cl">    <span class="nx">AppState</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">&#39;change&#39;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">appInFocus</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">public</span> <span class="nx">componentWillUnmount() {</span>
</span></span><span class="line"><span class="cl">    <span class="nx">AppState</span><span class="p">.</span><span class="nx">removeEventListener</span><span class="p">(</span><span class="s1">&#39;change&#39;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">appInFocus</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">private</span> <span class="nx">appInFocus</span> <span class="o">=</span> <span class="kr">async</span> <span class="p">(</span><span class="nx">nextAppState</span>: <span class="kt">any</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">nextAppState</span> <span class="o">===</span> <span class="s1">&#39;active&#39;</span> <span class="o">&amp;&amp;</span> <span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">autoTheme</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kr">const</span> <span class="nx">isDark</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">autoToggleTheme</span><span class="p">.</span><span class="nx">shouldToggleDarkTheme</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">      <span class="k">this</span><span class="p">.</span><span class="nx">context</span><span class="p">.</span><span class="nx">changeTheme</span><span class="p">(</span><span class="nx">isDark</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><h3 id="header">Header</h3>
<p>We have a single component in the MainApp page, which is a header, the header
will change logos depending on what the current theme is (again using context).
Here we are using React Hooks with our React Theme Context. Without needing to pass the theme as a prop.
This is particularly useful is this component was a is few levels deep, without
the hook we would need to keep passing the theme as a prop
to the child of a component from the parent, then that component would pass it to it&rsquo;s
child etc.</p>
<p>The context allows us have a global state throughout our app and
the hooks allow us to access this state without needing to turn our components into a class.
Though as you have seen we can also access the context within our React classes.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tsx" data-lang="tsx"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">Header</span> <span class="kr">as</span> <span class="nx">ElementsHeader</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;react-native-elements&#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">logoDark</span> <span class="kr">from</span> <span class="s2">&#34;~/assets/images/logo-dark.png&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">logoLight</span> <span class="kr">from</span> <span class="s2">&#34;~/assets/images/logo-light.png&#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">ThemeContext</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">&#34;~/providers/ThemeContext&#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">Header</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="p">{</span> <span class="nx">background</span><span class="p">,</span> <span class="nx">color</span><span class="p">,</span> <span class="nx">isDark</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">useContext</span><span class="p">(</span><span class="nx">ThemeContext</span><span class="p">).</span><span class="nx">theme</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</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">ElementsHeader</span>
</span></span><span class="line"><span class="cl">      <span class="na">containerStyle</span><span class="o">=</span><span class="p">{{</span> <span class="nx">backgroundColor</span>: <span class="kt">background</span> <span class="p">}}</span>
</span></span><span class="line"><span class="cl">      <span class="na">centerComponent</span><span class="o">=</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">flexDirection</span><span class="o">:</span> <span class="s2">&#34;row&#34;</span><span class="p">,</span> <span class="nx">flexWrap</span><span class="o">:</span> <span class="s2">&#34;wrap&#34;</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="na">style</span><span class="o">=</span><span class="p">{{</span> <span class="nx">color</span> <span class="p">}}&gt;</span><span class="nx">Example</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">Image</span>
</span></span><span class="line"><span class="cl">            <span class="na">source</span><span class="o">=</span><span class="p">{</span><span class="nx">isDark</span> <span class="o">?</span> <span class="nx">logoLight</span> : <span class="kt">logoDark</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="na">style</span><span class="o">=</span><span class="p">{{</span> <span class="nx">height</span>: <span class="kt">25</span><span class="p">,</span> <span class="nx">width</span>: <span class="kt">25</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">Text</span> <span class="na">style</span><span class="o">=</span><span class="p">{{</span> <span class="nx">color</span> <span class="p">}}&gt;</span><span class="nx">App</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">/&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></code></pre></div><h2 id="run-the-app">Run the app</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git clone git@gitlab.com:hmajid2301/articles.git
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> <span class="s2">&#34;articles/19. Theme your React Native app/ExampleApp&#34;</span>
</span></span><span class="line"><span class="cl">yarn
</span></span><span class="line"><span class="cl">yarn run start
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Then in another terminal</span>
</span></span><span class="line"><span class="cl">yarn run android
</span></span></code></pre></div><h2 id="example-app">Example App</h2>
<p>Here is a GIF of the app running.</p>
<p><img
        loading="lazy"
        src="/posts/2020-01-25-auto-toggle-dark-theme-on-your-react-native-app/images/demo.gif"
        type=""
        alt="Demo App"
        
      /></p>
<h2 id="appendix">Appendix</h2>
<p>That&rsquo;s it we successfully created an app that auto changes the user&rsquo;s theme depending on
the time of day, using the user&rsquo;s location to determine sunrise and sunset.</p>
<ul>
<li><a href="https://gitlab.com/hmajid2301/blog/-/tree/main/content/posts/2020-01-25-auto-toggle-dark-theme-on-your-react-native-app/source_code">Example source code</a></li>
</ul>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
