<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 👨‍💻 Perttu Lähteenlahti</title>
    <description>The latest articles on DEV Community by 👨‍💻 Perttu Lähteenlahti (@plahteenlahti).</description>
    <link>https://dev.to/plahteenlahti</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F153635%2F7a8840d7-339b-49c5-9ffa-2de5e06024d2.jpg</url>
      <title>DEV Community: 👨‍💻 Perttu Lähteenlahti</title>
      <link>https://dev.to/plahteenlahti</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/plahteenlahti"/>
    <language>en</language>
    <item>
      <title>Making Money with Your React Native App Throught In-app Purchases</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Sat, 18 Jan 2025 21:28:05 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/making-money-with-your-react-native-app-throught-in-app-purchases-5806</link>
      <guid>https://dev.to/plahteenlahti/making-money-with-your-react-native-app-throught-in-app-purchases-5806</guid>
      <description>&lt;p&gt;This article is based on the talk I gave at the first &lt;a href="https://www.reactnativelondon.co.uk/" rel="noopener noreferrer"&gt;React Native London conference in 2024&lt;/a&gt; about app monetization and in-app purchases. While selling your app on platforms like MicroAcquire or setting a price tag in the Play Store/App Store are valid strategies, the former isn’t very repeatable, and the latter feels somewhat outdated. In-app purchases have become the modern way to monetize apps. This article covers what you need to know about in-app purchases, how to set them up in your React Native app, and insights from psychology and service design on creating a great in-app purchase experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Brief history of in-app purchases
&lt;/h3&gt;

&lt;p&gt;Apple and Google introduced competing app stores toward the end of the 2010s. Initially, app stores followed a model similar to traditional software sales: users could try a free, limited version of an app, and if they liked it, they could purchase the full version and own it outright. This was the standard way software was sold. However, the shift toward continuous revenue streams eventually took hold, driven by the push for recurring income from customers. Perhaps influenced by this trend, Apple and Google both introduced their own in-app purchase frameworks, changing how apps are monetized.&lt;/p&gt;

&lt;p&gt;Today we have in-app purchases for all major platforms and they are most used solution for monetising apps. There are also multiple different types of in-app purchases. Let’s go over them and then talk which one works for your app the best.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consumables
&lt;/h3&gt;

&lt;p&gt;Consumables as the name entails are project that you purchase in the app and consume after purchasing. For example coin packs in mobile games, which you comsume and then use to purchase in-game items, or so called token of gratitude purchases such as sponsoring the developer by “buying them a coffee”. In both cases the in-app purchase flow makes it clear that your money is to purchase something that is one time and ephemeral.&lt;/p&gt;

&lt;p&gt;Mobile games are the best use case of consumables, as purchasing things is directly tied to the continued experience of playing the game, for example when your in-app purchases allow you to purchase potions to continue playing. Of course you could do something similar with limited use apps, if you have an app that allows user to create AI generated images, then every generation request could be handled as a consumable in-app purchase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Non-consumables
&lt;/h3&gt;

&lt;p&gt;Second type of in-app purchase is the non-consumable, which after purchasing stays with the users and never expires. If users uninstall the app, and later install it again, they can recover the non-consumable purchase as well. There are few ways which you can use non-consumables to monetize your app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Upgrading from lite version of the app to full version. This way there is no need for a separate light version of the app in the app stores.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unlocking an individual feature of the app, such as dark mode. This is similar to the gratitude purchase that consumables offer, as dark mode for example is not a feature user can’t live without (unlike developers would have you believe).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mobile games also use non-consumable purchases to unlock for example clothing for the player character. Alternative to this is to create an in-game currency that is a consumable purchase which is then used to purchase clothing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Non-consumables used to be a very common approach to providing limited/full-version unlock approach to apps. However the last type of in-app purchases, subscriptions, have mostly taken over this approach so let’s talk about those next.&lt;/p&gt;

&lt;h3&gt;
  
  
  Subscriptions
&lt;/h3&gt;

&lt;p&gt;The last and most ubiquous in-app purchase type is subscriptions. In-app purchases provide both recurring subscriptions, that are billed once a month for example; but also non-recurring once, where your subscription is on only for the mentioned timeframe and does not get automatically billed again.&lt;/p&gt;

&lt;p&gt;The point of subscriptions is of course to generate continuous revenue, and there a few reasons for this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Almost everything nowadays is connected to a server, and servers cost money. You have to somehow recoup the monthly server costs and subscriptions is a lot easier way to do that than trying to estimate a fixed price and then making users buy the app for that price.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Software is no longer just the app, but quite often there’s a underlying service layer providing e.g. customer support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Software moved from singular releases to continuous development. New features and bug fixes and released periodically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Getting payed for your work. Whether you are a solo developer or part of a big company, monthly revenue is also what turns into your monthly salary (well, one can dream)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx3y3h6so7keneifus9iv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx3y3h6so7keneifus9iv.png" alt="In-app purchases in action" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For these reason subscriptions have become so ubiquous. However building good subscription is not easy and a lot users are still rather subscriptions avoidant. It is not uncommon for example to come across following type of reviews in app stores:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“App solved my problem but requires a subscription to use the service more than 5 times. One star”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because of how easy and likely it is for users to shy away from your app because it has subscriptions, creating great subscription experiences becomes crucial for making money with your app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding commissions
&lt;/h3&gt;

&lt;p&gt;In-app purchases are just digital payments in mobile app context. However, the you we can’t just slap a Stripe payments into your app to monetize your services and content. Apple and Google both whant their pound of flesh in the form of a commission.&lt;/p&gt;

&lt;p&gt;The ina-app purchase commission used to be 30% for both App store and Play store, with both programs offering a reduced 15% commission fee for the first one million in revenue if you enrolled in the small business programs. Going beyond that, and you’ll start paying the original 30% commission. This applies to all in-app purchases, but subscriptions have an additional term to them that makes longer running subscriptions more profitable: both Apple and Google take a reduced 15% commissions that user has been subscribing for more than a year.&lt;/p&gt;

&lt;p&gt;To calculate how much money you get when a user pays 10 euros, you have to first deduct the value added tax of your market, and then deduct the commission based on the store and program you’re in. In case of Finland this is 25.5% VAT, which means you’re left with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Deduct VAT (25.5%): €10 × (1–0.255) = &lt;strong&gt;€7.45&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deduct Apple’s commission:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If 15%: €7.45 × (1–0.15) = &lt;strong&gt;€6.33&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If 30%: €7.45 × (1–0.30) = &lt;strong&gt;€5.22&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So you’re left with &lt;strong&gt;€6.33 (15%)&lt;/strong&gt; or &lt;strong&gt;€5.22 (30%)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, if you’re in a European country, thanks to the new terms of the Digital Markets Act, you can opt-in for Apple’s new reduced commission rate of 17% for all apps, and 10% commission for businesses in small business programs. On top of this, if you’re using Apple’s in-app purchase system, then you need to add 3% on top of either of these to get the full commission. However, if your app downloads exceed over 1 million, you get an extra “Apple’s core technology” fee of 0.5 euros per every download per year. If you’re doing business in Europe you have some choice, but most likely it’s the easiest to get started with the traditional fee model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reader app status - circumventing the commission
&lt;/h3&gt;

&lt;p&gt;There is no way to circumvent Apple and Google’s commissions if you’re selling digital services or monetizing your content through your app. Of course if you’re selling physical goods, such as food deliveries, then the in-app purchase rules don’t apply to you.&lt;/p&gt;

&lt;p&gt;Alternatively you can also not sell anything in your app, but handle the sales through your own website, using for example Stripe. This is how Kindle and Spotify get around Apple’s limitations. To do the same you have to apply a separate reader app status. To get accepted requires putting your app to be behind a login, and users can only consume already purchased content in the app. All payments need to be done through a separate channel and there are some limitations on how you can direct the user to our own site to do it. Directly linking them into payment process for example will not work, but you can for example say:&lt;/p&gt;

&lt;p&gt;“Go to the website to purchase subscription”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2sse1d4n3aq60ak508i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2sse1d4n3aq60ak508i.png" alt="How Spotify handles off app purchasing" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  In-app purchases in React Native
&lt;/h2&gt;

&lt;p&gt;Since React Native has been around 8 years already, there’s quite a lot of options for in-app purchase for it. For example&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/hyochan/react-native-iap" rel="noopener noreferrer"&gt;&lt;strong&gt;react-native-iap&lt;/strong&gt;&lt;/a&gt; which has been around for sometime. A good choice for consumable purchases but slightly complicated for subscriptions which usually require server side events to manage the subscriptions well.&lt;br&gt;&lt;br&gt;
&lt;em&gt;2.9k stars in GitHub&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/chargebee/chargebee-react-native" rel="noopener noreferrer"&gt;&lt;strong&gt;react-native-chargebee&lt;/strong&gt;&lt;/a&gt;, a good choice if you’re in a situation where your payment infra already exists in Chargebee. From personal experience, the integration seems more like an afterthought for Chargebee, and its documentation is very confusing, with setting up being needlessly complex.&lt;br&gt;&lt;br&gt;
&lt;em&gt;8 stars in GitHub&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/RevenueCat/react-native-purchases" rel="noopener noreferrer"&gt;&lt;strong&gt;react-native-purchases&lt;/strong&gt;&lt;/a&gt;, the iap package by RevenueCat. It’s solid, documentation is good, there’s extra stuff like paywalls, and you offer integrations with Stripe for example.&lt;br&gt;&lt;br&gt;
&lt;em&gt;804 stars in GitHub&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both Chargebee and RevenueCat offerings are what you would call hosted options, meaning the package is not enough by itself, but instead you will be using their payment infra to manage payements and receipts. In the case of RevenueCat, it’s free to get started with but once you make over 2.5k dollars you start paying 1% commissions on all tracked revenue.&lt;/p&gt;

&lt;p&gt;In most cases you want to go with this kind of an approach. Running your own server to manage in-app purchases receipt validation for example is quite the hassle. I recently worked in one project where we had to wire our own consumable purchases to the custom backend and to be honest, I would take almost anything over working with Apple’s in-app server APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Setting up RevenueCat and App store and Playstore&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In order for things to work correctly we need to do some configuration in RevenueCat and App Store / Play Store. Way things works is that Play Store and App Store need to have products in them that we then connect to RevenueCat. This is easier to explain by example so start navigate to your App store connect account and first create this subscription group&lt;/p&gt;

&lt;p&gt;After creating the subscription group we need to add two subscriptions into it, and then add the translations. We don’t need so submit anything yet but it necessary to get into a stage that says “Ready to submit”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d43ikihjqswjv2ydcuu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7d43ikihjqswjv2ydcuu.png" alt="In-app purchases in action" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should end up with something similar to this once. Missing metadata means that you still have to fill in things, although the subscriptions should already show up in sandboxtesting.&lt;/p&gt;

&lt;p&gt;Next step is to configure these in RevenueCat. You can do this manually or you can configure your App Store keys into RevenueCat and allow RevenueCat to import your products from App Store. Before we get into all that it’s important to note that RevenueCat offers quite a lot more configuration options for in-app purchases than Play Store and App Store, and they also use custom concepts for it. Let’s look at few of the key ones before continuing with the configuration:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entitlements —&lt;/strong&gt; put simply this is the level of access user is entitled to. Your app could have multiple levels of entitlements that unlock different levels of features for example. In terms of real world examples, Netflix offers different subscriptions, which are similar to entitlements: basic one with 720p resolution and only one device, and family one with 4k and multiple devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Products&lt;/strong&gt; are what RevenueCat calls the subscriptions and other in-app purchases you’ve set up in App Store connect and Play Store console. Products should match the subscriptions we’ve set up earlier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Offerings&lt;/strong&gt; allows us to map together different products and show them together. RevenueCat’s paywall functionality for example makes use of the offerings&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paywall&lt;/strong&gt; is a method for limiting access to content, and RevenueCat offers a built-in functionality to create these and configure them remotely without any code.&lt;/p&gt;

&lt;p&gt;Now that you understand these concepts you should understand the next steps for configuring our in-app purchases in RevenueCat dashboard. Due to having a monthly and yearly subscription for our app in App Store connect, we need to create two corresponding product, one entitlement that is connected to those products called &lt;em&gt;Pro subscription&lt;/em&gt;, and one offering which will have both of those products. Once that is done, navigate to the &lt;em&gt;&lt;strong&gt;Paywalls&lt;/strong&gt;&lt;/em&gt; section of the tool and create our first paywall with the one offering we made.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7dv78rgymai9yshy8agg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7dv78rgymai9yshy8agg.png" alt="In-app purchases in action" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should now have the fundamentals building blocks for showing two subscription options in our React Native app. You can go ahead and customize the paywall to your needs. Once you ready, continue to next section which goes over the react-native-purchases configuration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhu6zzpo0mwksn1l3zugq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhu6zzpo0mwksn1l3zugq.png" alt="In-app purchases in action" width="800" height="651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding and configuring react-native-purchases
&lt;/h3&gt;

&lt;p&gt;React-native-purchases provides a lot of functionality out of the box without having to write a lot of code. You probably already have a project in which you’re going to configure your in-app purchases, but in case you do not, you can clone the repository below which contains the basic setup and the code examples we are going to go through next&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example project: &lt;a href="https://github.com/plahteenlahti/buystuff" rel="noopener noreferrer"&gt;plahteenlahti/buystuff&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everything begins with installing the necessary packages, &lt;code&gt;react-native-purchases&lt;/code&gt; and &lt;code&gt;react-native-purchases-ui&lt;/code&gt;. The latter will become more important later on when we start to work with the paywalls.&lt;/p&gt;

&lt;p&gt;After installing all the necessary packages, we need to initialize the &lt;code&gt;react-native-purchases&lt;/code&gt; module when mounting our app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Platform&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Purchases&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-purchases&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Enable dev logging, you can remove this line&lt;/span&gt;
  &lt;span class="nx"&gt;Purchases&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setLogLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Purchases&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LOG_LEVEL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Initialize the module using Platform.select&lt;/span&gt;
  &lt;span class="nx"&gt;Purchases&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Platform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;ios&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your_ios_api_key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your_android_api_key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s important to notice that &lt;code&gt;apiKey&lt;/code&gt; is a single field but our Android and iOS apps have different key. Using &lt;code&gt;Platform.select&lt;/code&gt; we can easily get around this. The API key is a public key so we don’t have to worry about the key getting bundled without our app.&lt;/p&gt;

&lt;p&gt;With this done, we are ready to start restricting user access to the app and presenting paywalls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before purchase — Displaying a paywall
&lt;/h3&gt;

&lt;p&gt;We are going to talk about the best possible way to structure you in-app purchase flow, which usually doesn’t start with instantly showing a paywall. However to keep the examples clear, let’s put aside for now and instead focus on the code implementation and not the UX.&lt;/p&gt;

&lt;p&gt;As mentioned, paywalls are a way of restricting user’s acces to certain content or functionality in your app. Let’s say for example that user is trying to download a wallpaper app, and they press on the wallpaper they are intersted in seeing in full screen. Instead of opening in full screen, they are taken to a new screen which tells them to subscribe for 2.99€ a month. A prime example of a paywall. With RevenueCat, achieving similar functionality is very easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;RevenueCatUI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-purchases-ui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;showPaywall&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setShowPaywall&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SafeAreaView&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StatusBar&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"auto"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TouchableOpacity&lt;/span&gt;
            &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imageContainer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setShowPaywall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;
              &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;imageUrl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="na"&gt;resizeMode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"cover"&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TouchableOpacity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;
        &lt;span class="na"&gt;presentationStyle&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pageSheet"&lt;/span&gt;
        &lt;span class="na"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showPaywall&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;animationType&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"slide"&lt;/span&gt;
        &lt;span class="na"&gt;onRequestClose&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setShowPaywall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RevenueCatUI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Paywall&lt;/span&gt;
          &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;onDismiss&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setShowPaywall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;displayCloseButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Modal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;SafeAreaView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above I want you to pay attention to few things. First, in order to show the RevenueCat paywall you need the react-native-purchases-ui package that was installed ealier. Second is how I’ve structured the actual paywall. Whether to show the paywall or not is dependant on the showPayWall state. Later on we will tie this to react-native-purchases methods for checking user’s entitlements, but this simple approach is enough for now.&lt;/p&gt;

&lt;p&gt;I wanted to display the paywall inside a modal that jumps on top whatever is on the screen and wrapped it in React Native’s modal component. In a more complex app you could make the paywall part of the navigation stack, which opens up more possibilities for displaying for it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fth5728m7hd0xoon2bm8g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fth5728m7hd0xoon2bm8g.gif" alt="In-app purchases in action" width="800" height="450"&gt;&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Once you’ve implemeted this part of the code, you should see the paywall you configured in RevenueCat. If nothing is showing up it’s time to check your configurations and the debug log for potential errors. Try also making changes to your paywall in RevenueCat’s dashboard and you should see them reflected on the app after a refresh. To test purchases you need to run the app on a real device and configure a sandbox testing account for that, see &lt;a href="https://developer.apple.com/help/app-store-connect/test-in-app-purchases/create-a-sandbox-apple-account/" rel="noopener noreferrer"&gt;Apple’s up to date guide on how to do that here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  After purchase — Checking user’s entitlements
&lt;/h3&gt;

&lt;p&gt;Now that we have our basic purchasing flow set up using the RevenueCat’s paywall functionality, it’s time to check user’s subscription status i.e. are they entitled to the content they are trying to access. In RevenueCat this is done by calling the await Purchases.getCustomerInfo() and checking if the users active entitlements contain the entitlement that is required to access that content. CustomerInfo is catched by RevenueCat so it’s safe to call in multiple times, therefore the easiest way to implement entitlement checking feature is to create a custom hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Purchases&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-purchases&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useAppContentAccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;hasAccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setHasAccess&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkCustomerEntitlement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customerInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Purchases&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCustomerInfo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Replace 'pro_access' with the actual entitlement ID you set in RevenueCat&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entitlementActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;customerInfo&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;entitlements&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pro_access&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="nf"&gt;setHasAccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;entitlementActive&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// User has access if entitlement is active&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error checking customer entitlement:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setHasAccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Default to no access on error&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;checkCustomerEntitlement&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;hasAccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use this hook in all parts of the app that require checking the user’s access level to that subscription content like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ActivityIndicator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useAppContentAccess&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./hooks/useAppContentAccess&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;hasAccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAppContentAccess&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ActivityIndicator&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;hasAccess&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome to the premium content!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Please subscribe to access this content.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now have all the fundamentals building blocks for building in-app purchase flows in your React Native app. Let’s next look at the fundamentals behind good in-app purcase flows and a little bit of user psychology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Psychology of good in-app purchase experiences
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa8isdc95jy1ytiuathb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa8isdc95jy1ytiuathb.png" alt="In-app purchases in action" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting user to buy
&lt;/h3&gt;

&lt;p&gt;In app purchases are not the main use case of your app, you should not be spending time on building them, they bring no value to the users and I don’t think I’ve ever heard anyone say “I love building in-app purchases”. So sure, you can build your in-app purchases on anything you want, build your custom stuff for it if you feel, but keep in mind that no user is ever going to give you money or 5 star rating because your in-app purchase screen was artisanally made.&lt;/p&gt;

&lt;p&gt;What you should spend your time instead is thinking of how to build the best in-app purchase flow. What I mean by that is thinking about the user goals and actions that lead them to first discover how your app solves their problems, and then commit to paying it to you. We should start by first thinking about what is the user problem our app is focused on solving for the user. That is after all why we’ve built the app originally. That functionality should of course be very visible in all the App store and Play store listings so so that users download the app in the first place. Of course it should also be so that main functionality is the easiest one to find from to find from both the store’s marketing as well as when the user opens your app the first time.&lt;/p&gt;

&lt;p&gt;Once we have the problem clearly in mind it’s time to think about how we show that our app has that exact functionality that they are looking for. For this we have few options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Can we allow the users to use functionality in the app and get results and then limit it. For example, in our wallpaper app we could maybe allow the users to download one wallpaper for free&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can we give the users a free trial of the full app? For example let’s say that when they subscribe for a month they get 1 week free during which they can cancel the subscription&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Give something for free, a little bit more for some amount of money, and then give full access to everything for money. A ladder-esque approach where user becomes a more engaged customer as a function of feature amount&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Life cycle of in-app purchases
&lt;/h3&gt;

&lt;p&gt;Depending what you’re selling in your app, the customer journey is always different. One time purchases and continuous subscriptions pose different challenges for the customer journey. For time sake I’m only going to use subscriptions as an example of how to map your customer journey:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;User discovers app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User discovers the value promise of the subscription&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User decides to commit to buying subscription&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User decides to increase spending in the app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User churns, ends subscription&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course in an optimal world the user never churns out, but in real life people run out of money, their priorities change, or your app stops being valuable. Only the last one is something you directly improve. For the other parts you can only provide a stellar experience, so the problems you’re trying to solve becomes how to support users in all parts of the customer journey:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Highlight new value of the app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Offer free trials&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Offer discounts on longer subscription&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Highlight how old purchase is pro-rated&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnstnrjjaar1jlg8f52ge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnstnrjjaar1jlg8f52ge.png" alt="In-app purchases in action" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;You’ve made it to the end, to recap you should now have a pretty good understanding of in-app purchase on different platforms, the options for doing that in React Native, example of in-app purchases using Revenucat and react-native-purchases, and the user psychology of a good in-app purchase experience. With these you should be able to create a basic in-app purchase flow that converts users to paying users. If you’re interested in learning more I suggest looking at RevenueCat’s developer documentation which contains a lot good information and technical aspects of in-app purchases.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>iap</category>
    </item>
    <item>
      <title>I built a React Native App to Manage Netlify Hosted Sites</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Wed, 10 Feb 2021 20:33:43 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/i-built-a-react-native-app-to-manage-netlify-hosted-sites-192c</link>
      <guid>https://dev.to/plahteenlahti/i-built-a-react-native-app-to-manage-netlify-hosted-sites-192c</guid>
      <description>&lt;p&gt;Today I'm announcing &lt;a href="https://netli.fyi?source=dev.to"&gt;Netli.fyi&lt;/a&gt; a small app that helps you to manage your Netlify sites on the go. It's built with React Native and uses the Netlify API to show you your Netlify sites, builds logs, deployments, and form submissions. &lt;/p&gt;

&lt;p&gt;Despite being mostly a mobile developer, I built quite a lot of websites and web apps with Gatsby, Publish, and NextJS during the last two years. The majority of these are hosted by Netlify, because I love the ease of use it provides: deploy previews, form submissions and functions work exactly like I would want them to. The Netlify site is pretty good for managing stuff with a desktop browser. However I needed something to make it faster to do while on the go, so I ended up building Netli.fyi&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1359597977980047363-424" src="https://platform.twitter.com/embed/Tweet.html?id=1359597977980047363"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1359597977980047363-424');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1359597977980047363&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;The app is built with React Native and makes use of the following packages&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;react-navigation&lt;/li&gt;
&lt;li&gt;react-native-svg&lt;/li&gt;
&lt;li&gt;react-native-vector-icons&lt;/li&gt;
&lt;li&gt;react-native-app-auth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When it comes to future features, I'm currently working on making it possible to redeploy sites from the app, see Netlify functions related information. In addition to I think some kind of iOS home screen widget would be a pretty nice addition, and after thinning the app a little I think I could a subset of features into an Apple AppClip as well which would make it easier to try the app.&lt;/p&gt;

&lt;p&gt;The app is available for both iOS and Android for the price of a cup of tea, but you can also enroll in the open beta programs for either platform to give the app a try. I would love you to try the app and give feedback on what features you would like to see 🙂&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>netlify</category>
    </item>
    <item>
      <title>I made the React Native app I've been building for the last year open source</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Mon, 31 Aug 2020 20:11:41 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/i-made-the-react-native-app-i-ve-been-building-for-the-last-year-open-source-44le</link>
      <guid>https://dev.to/plahteenlahti/i-made-the-react-native-app-i-ve-been-building-for-the-last-year-open-source-44le</guid>
      <description>&lt;p&gt;TLDR: &lt;a href="https://github.com/hello-nyxo/nyxo-app"&gt;here's react-native sleep tracking &amp;amp; sleep coaching app that I've been building&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In January 2019 I took a big leap into startup entrepreneurship and started building an app that could provide advice on how to improve your sleep based on your sleep tracker's data. When I started building it I had very little experience with React and even less experience with React Native. Because of having so little experience, I was afraid to make the code publicly available despite wanting to do it so from the start. &lt;/p&gt;

&lt;p&gt;Few weeks I finally found the courage to clean the project and switch from private Gitlab repo to a public Github repository. You can find the full code here. I've tried to provide all the necessary instructions on how to run it locally, but there might be a few mistakes on my part here and there. Please let me know if/when you come across them.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/hello-nyxo"&gt;
        hello-nyxo
      &lt;/a&gt; / &lt;a href="https://github.com/hello-nyxo/nyxo-app"&gt;
        nyxo-app
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The repository for Nyxo React Native app, a personal sleep tracker and sleep coach
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/hello-nyxo/nyxo-website/blob/master/static/images/cover.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vR9uocSQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/hello-nyxo/nyxo-website/raw/master/static/images/cover.png" alt="Nyxo App"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Nyxo App – Better Sleep 💤💤💤&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/prettier/prettier"&gt;&lt;img src="https://camo.githubusercontent.com/c25ebde472e0782be29045b182f0ae67c8e8e2d2897e3d65ca8f9a200c787c98/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f64655f7374796c652d70726574746965722d6666363962342e7376673f7374796c653d666c61742d737175617265" alt="code style: prettier"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/cd8719589883a99b5588b9531b9c45ce41804c16e3bf3460d41ea2476a97947e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f772f68656c6c6f2d6e79786f2f6e79786f2d617070"&gt;&lt;img src="https://camo.githubusercontent.com/cd8719589883a99b5588b9531b9c45ce41804c16e3bf3460d41ea2476a97947e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f772f68656c6c6f2d6e79786f2f6e79786f2d617070" alt="commit activity"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/fa91f5467e6d98a1517559fd687c32938cfc344939e489657e1bf835f5c7b6d6/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f68656c6c6f2d6e79786f2f6e79786f2d617070"&gt;&lt;img src="https://camo.githubusercontent.com/fa91f5467e6d98a1517559fd687c32938cfc344939e489657e1bf835f5c7b6d6/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f68656c6c6f2d6e79786f2f6e79786f2d617070" alt="release"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/16ee90973142801313037c05ad074396d3616a23d77cbef7356f7d207b0672d7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f68656c6c6f2d6e79786f2f6e79786f2d617070"&gt;&lt;img src="https://camo.githubusercontent.com/16ee90973142801313037c05ad074396d3616a23d77cbef7356f7d207b0672d7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f68656c6c6f2d6e79786f2f6e79786f2d617070" alt="license"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://apps.apple.com/us/app/nyxo-sleep-coaching/id1440417031" rel="nofollow"&gt;Download iOS&lt;/a&gt; • &lt;a href="https://play.google.com/store/apps/details?id=fi.nyxo.app" rel="nofollow"&gt;Download Android&lt;/a&gt; • &lt;a href="https://github.com/hello-nyxo/nyxo-appmailto:hello+github@nyxo.fi"&gt;Contact&lt;/a&gt; • &lt;a href="http://eepurl.com/g-0zKD" rel="nofollow"&gt;Nyxo Newsletter&lt;/a&gt;
&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://testflight.apple.com/join/jhNZ8CC7" rel="nofollow"&gt;Public beta for iOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://play.google.com/apps/testing/fi.nyxo.app" rel="nofollow"&gt;Public beta for Android&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What is Nyxo App&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Nyxo is a mobile application for improving your sleep. Its built with React Native, AWS Amplify, styled-components, and Redux. Nyxo provides the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sleep tracking, with support for multiple different trackers
&lt;ul&gt;
&lt;li&gt;Google Fit&lt;/li&gt;
&lt;li&gt;Apple Health&lt;/li&gt;
&lt;li&gt;Oura&lt;/li&gt;
&lt;li&gt;Withings&lt;/li&gt;
&lt;li&gt;Fitbit&lt;/li&gt;
&lt;li&gt;Polar&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Sleep trends and sleep diary&lt;/li&gt;
&lt;li&gt;Nyxo Cloud: backup your sleep data and coaching progress, and access it from &lt;a href="https://nyxo.app" rel="nofollow"&gt;nyxo.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;4 week sleep coaching program&lt;/li&gt;
&lt;li&gt;Ask experts, if you have any questions we have the professional sleep coaches to help&lt;/li&gt;
&lt;li&gt;And more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The plan is to develop Nyxo further and allow contributions from everyone. If you want to for example build a new sleep visualization or add support for new sleep tracker, we will gladly welcome a pull request of that :)&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Can&lt;/h2&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/hello-nyxo/nyxo-app"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Why this project might be interesting to you?
&lt;/h2&gt;

&lt;p&gt;As mentioned I built it with React Native, while originally having very little experience on it. I would like to say that I've improved a lot since starting out, so in a way this project works as a timeline of how I learned to build stuff with React Native. There are parts in the project where the code is really ugly, but also parts where I'm a little proud of it even.&lt;/p&gt;

&lt;p&gt;To give a little rundown of the app here's what it can do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import sleep data from the following sources

&lt;ul&gt;
&lt;li&gt;Apple Health&lt;/li&gt;
&lt;li&gt;Google Fit&lt;/li&gt;
&lt;li&gt;Oura&lt;/li&gt;
&lt;li&gt;Garmin&lt;/li&gt;
&lt;li&gt;Polar&lt;/li&gt;
&lt;li&gt;Fitbit&lt;/li&gt;
&lt;li&gt;Withings&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Save data to Apple Health&lt;/li&gt;
&lt;li&gt;Create trackable habits &lt;/li&gt;
&lt;li&gt;Show stats based on sleep: bedtime window, average sleep, sleep trend, shortest night, longest night, etc.&lt;/li&gt;
&lt;li&gt;Save data to Nyxo Cloud Service, which is built with Aws Amplify&lt;/li&gt;
&lt;li&gt;Display content about sleep from Contentful&lt;/li&gt;
&lt;li&gt;Works on both iOS and Android&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There also some more boring features, which you can explore better by downloading the app from either &lt;a href="https://apps.apple.com/us/app/nyxo-sleep-coaching/id1440417031"&gt;App Store&lt;/a&gt; or &lt;a href="https://play.google.com/store/apps/details?id=fi.nyxo.app"&gt;Play Store&lt;/a&gt;. One really crucial thing that is missing is onboarding, which I'm hoping to add as soon as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech
&lt;/h3&gt;

&lt;p&gt;The app is built with the following stuff:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Amplify: S3, Cognito, AppSync, DynamoDB, Aws Lambda&lt;/li&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;Redux, reselect, redux-offline&lt;/li&gt;
&lt;li&gt;react-native-reanimated&lt;/li&gt;
&lt;li&gt;react-native-svg&lt;/li&gt;
&lt;li&gt;Intercom&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Continuity
&lt;/h2&gt;

&lt;p&gt;This is project is also very much alive and I'm contributing to it daily. If you like the app, I would really appreciate it if you give it a star either in Github or in App store / Play store. It would mean a lot to me, and make my whole week :)&lt;/p&gt;

&lt;p&gt;PS.&lt;/p&gt;

&lt;p&gt;I've also built another app during the past year. This app also doubles as a website for Nyxo, as it's built with Gatsby, Amplify, TypeScript, Styled-components, and react-query. You can find that project below:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/hello-nyxo"&gt;
        hello-nyxo
      &lt;/a&gt; / &lt;a href="https://github.com/hello-nyxo/nyxo-website"&gt;
        nyxo-website
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Nyxo website, built with Gatsby, AWS Amplify, React and TypeScript
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Nyxo Website – Better Sleep 💤💤💤&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;
  &lt;a href="https://apps.apple.com/us/app/nyxo-sleep-coaching/id1440417031" rel="nofollow"&gt;Download iOS&lt;/a&gt; • &lt;a href="https://play.google.com/store/apps/details?id=fi.nyxo.app" rel="nofollow"&gt;Download Android&lt;/a&gt; • &lt;a href="https://github.com/hello-nyxo/nyxo-websitemailto:hello+github@nyxo.fi"&gt;Contact&lt;/a&gt; • &lt;a href="http://eepurl.com/g-0zKD" rel="nofollow"&gt;Nyxo Newsletter&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hello-nyxo/nyxo-website#contributors-"&gt;&lt;img src="https://camo.githubusercontent.com/9350ac36bbe8fa7813f89cfe221ca5a3af14e04fb565456859bb323d5d945c3a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f616c6c5f636f6e7472696275746f72732d342d6f72616e67652e7376673f7374796c653d666c61742d737175617265" alt="All Contributors"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/hello-nyxo/nyxo-website/workflows/Build,%20test,%20and%20release/badge.svg"&gt;&lt;img src="https://github.com/hello-nyxo/nyxo-website/workflows/Build,%20test,%20and%20release/badge.svg" alt="Build, test, and release"&gt;&lt;/a&gt;
&lt;a href="https://github.com/prettier/prettier"&gt;&lt;img src="https://camo.githubusercontent.com/c25ebde472e0782be29045b182f0ae67c8e8e2d2897e3d65ca8f9a200c787c98/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f64655f7374796c652d70726574746965722d6666363962342e7376673f7374796c653d666c61742d737175617265" alt="code style: prettier"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/634aff2fa3c11e31f7ea9a8ee35496ab6a0a13a5bd5463a9c13d3fe1f3e3f9dd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f772f68656c6c6f2d6e79786f2f6e79786f2d77656273697465"&gt;&lt;img src="https://camo.githubusercontent.com/634aff2fa3c11e31f7ea9a8ee35496ab6a0a13a5bd5463a9c13d3fe1f3e3f9dd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f772f68656c6c6f2d6e79786f2f6e79786f2d77656273697465" alt="commit activity"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/6f02b338e78e35a7b8ba54cdcd5f353bb407155bc02776d8c2cffd569fe3fb35/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f68656c6c6f2d6e79786f2f6e79786f2d77656273697465"&gt;&lt;img src="https://camo.githubusercontent.com/6f02b338e78e35a7b8ba54cdcd5f353bb407155bc02776d8c2cffd569fe3fb35/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f68656c6c6f2d6e79786f2f6e79786f2d77656273697465" alt="release"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/c189ef8ff161d86875de06c3972fa68d4b80bb6f42e8ad9e8926fa352e509778/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f68656c6c6f2d6e79786f2f6e79786f2d77656273697465"&gt;&lt;img src="https://camo.githubusercontent.com/c189ef8ff161d86875de06c3972fa68d4b80bb6f42e8ad9e8926fa352e509778/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f68656c6c6f2d6e79786f2f6e79786f2d77656273697465" alt="license"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is the website that powers &lt;a href="https://nyxo.app" rel="nofollow"&gt;nyxo.app&lt;/a&gt;. It's built with the following tools:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gatsby&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;styled-components&lt;/li&gt;
&lt;li&gt;aws-amplify&lt;/li&gt;
&lt;li&gt;Netlify&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Quick start&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;1. &lt;strong&gt;Install the Gatsby CLI.&lt;/strong&gt;
&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install -g gatsby-cli&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2. &lt;strong&gt;Setup AWS Amplify + environment variables&lt;/strong&gt;
&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;In order to develop the site, you need to create file called &lt;code&gt;.env.development&lt;/code&gt; in the root of the project. The contents of the file should we following:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;INSTAGRAM_API_TOKEN=YOUR_KEY
INSTAGRAM_BUSINES_ID=YOUR_KEY
GTAG_ID=YOUR_KEY
GOOGLE_ANALYTICS=YOUR_KEY
CONTENTFUL_SPACE_ID=YOUR_KEY
CONTENTFUL_ACCESS_TOKEN=YOUR_KEY
CONTENTFUL_ENVIRONMENT=YOUR_ENVIRONMENT
MAILCHIMP_ENDPOINT=YOUR_KEY
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We use Contentful so serve our coaching data. When development you can use our public testing environment by placing the following values in it:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;CONTENTFUL_SPACE_ID=2bj8pq0ood89
CONTENTFUL_ACCESS_TOKEN=7yCg2oVBg-kQAhPrNTI0935HDiUJ7FYlUyIwM3Tspgg
CONTENTFUL_ENVIRONMENT=public
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Our Instagram component will most likely complain that it can fetch data, because you're missing the required tokens. We are working on how to disable this. For now you should be able to skip…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/hello-nyxo/nyxo-website"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>opensource</category>
      <category>reactnative</category>
      <category>amplify</category>
    </item>
    <item>
      <title>Nyxo.app Now Available in Both Finnish and English</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Fri, 14 Aug 2020 08:53:24 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/nyxo-app-now-available-in-both-finnish-and-english-6nn</link>
      <guid>https://dev.to/plahteenlahti/nyxo-app-now-available-in-both-finnish-and-english-6nn</guid>
      <description>&lt;p&gt;Starting today, all of the materials we've produced about sleep, such as the lesson and exercises, are available in Finnish and English. We've supported both of the two aforementioned languages in the Nyxo mobile app since the beginning. Still, our website has mostly been in English. However, starting from today, you can easily change the language in the top navigation. In addition to this, we are now capable of supporting additional languages as well, and you can contribute to the translation in our repository.&lt;/p&gt;

&lt;p&gt;There are a few things we hope to accomplish with this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Better support for our Finnish customers. Our biggest market is still Finland; for a reason, we see that it is crucial to provide support and coaching materials in that language.&lt;/li&gt;
&lt;li&gt;Better SEO performance. We hope that finally, supporting two languages throughout the site will boost our search engine position.&lt;/li&gt;
&lt;li&gt;Open the way for more translations. Now that our source is open, everyone is welcome to provide additional languages, and we can also commission new languages if a certain market it requires. One example of this is supporting Swedish, the second official language here in Finland.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before going into details on how the additional languages where implemented, I want to thank Pietari Nurmi and Kayla Gordon for translating and fixing the existing translations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Aspects When Converting to a Multi-language Page
&lt;/h2&gt;

&lt;p&gt;The nyxo.app site has been built using &lt;a href="http://gatsbyjs.org/"&gt;GatsbyJS&lt;/a&gt;, a static site generator. We've written previously about using Gatsby in our blog, and overall find it a very exciting piece of technology to work with. However, localization with Gatsby is not the easiest thing to achieve, and we have tried to do it previously, but the amount of work has just been too much for the benefit.&lt;/p&gt;

&lt;p&gt;This time we decided to try it again after coming across &lt;a href="https://github.com/microapps/gatsby-plugin-react-i18next"&gt;gatsby-plugin-react-i18next&lt;/a&gt;. Using it made the whole localization project almost painless (we did have some problems with getting it to play nicely with the pages created using our content management service). What makes this plugin different from other Gatsby plugins is that it uses react-i18next, which is most likely one of the best options for handling localization.&lt;/p&gt;

&lt;p&gt;Our site uses this plugin, with JSON translation files to translate all the UI texts, such as the ones appearing inside buttons, and on most pages which are coaching lessons or exercises. Our sleep coaching materials are fetched from Contentful, and then using the custom page creation function, we create individual pages for all languages. Currently, this means that Gatsby generates close to 500 pages, 250 in each of the currently supported languages. Adding for example, two more languages will massively increase the amount of generates pages. However, as long as the amount of generated pages stays under 10k, all should be good. Over that, we will most likely need to start considering an alternative solution.&lt;/p&gt;

&lt;p&gt;We will most likely write a more detailed guide on how you can do this yourself, but in the meantime, you can peek at the code in our repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Still to come
&lt;/h3&gt;

&lt;p&gt;There are still some things missing as well. For example, blog posts are currently only available in one language and don't even support multiple versions of the content. There might also be some missing translation around the site, due to the number of unique pages we have. If you notice something, you can open a ticket in our repository.&lt;/p&gt;

</description>
      <category>company</category>
      <category>opensource</category>
      <category>jamstack</category>
    </item>
    <item>
      <title>Nyxo.app website is now open-source</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Fri, 07 Aug 2020 08:58:35 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/nyxo-app-website-is-now-open-source-502o</link>
      <guid>https://dev.to/plahteenlahti/nyxo-app-website-is-now-open-source-502o</guid>
      <description>&lt;h4&gt;
  
  
  Hello world!
&lt;/h4&gt;

&lt;p&gt;Today and I'm very excited to announce that we have just open-sourced the Nyxo.app website, that means &lt;a href="https://nyxo.app"&gt;this one&lt;/a&gt;. This is the first step in a larger project of making all Nyxo products open source. In the future, we will open-source more the things we've built here at Nyxo.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Nyxo
&lt;/h3&gt;

&lt;p&gt;In case this is the first time you've heard about Nyxo, let me introduce what we do. Founded in 2019, we build products to help you sleep better because we believe that sleep is the cornerstone of a healthy, happy, and fulfilling life. Our strategy for doing this is to provide something we call sleep coaching. Sleep coaching, which incorporates your sleep data to drive a four-week coaching program. Because we use data such as sleep records, heart rate, and daily activity to influence what type of coaching lessons and exercises are right for you, we work hard to support various sleep and activity trackers. You can also take part in the coaching without buying any tracker because the journey to better sleep, should not require an expensive upfront purchase.&lt;/p&gt;

&lt;p&gt;We also strongly believe that a tightly knitted connection to sleep and behavioral research is the only way to develop coaching. Many in our team have a background in cognitive science or psychology, and we actively drive to be science-driven.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why We're Going Open Source
&lt;/h3&gt;

&lt;p&gt;Since founding Nyxo, we've been planning to build the product in public and allow everyone to contribute to it. However, because we are building products that employ the user's well-being data, we were concerned about how privacy and security would work in open source settings. However, as time has shown, obscurity does not equal security, and when you're product makes use user's private data, you have to be transparent how that data is used. We've concluded that the best way to tackle both of these subjects is to be as open as possible. It will allow users to understand better how their data is used in our products and also allow us to learn from other people interested in contributing.&lt;/p&gt;

&lt;p&gt;We also strongly believe that open source will allow us to build better products, solve more problems. Innovation, both radical and incremental, is not born out of a void, but out of interaction with the real world. Building a product that everyone can contribute to is a perfect way to do this.&lt;/p&gt;

&lt;p&gt;Last but not least, we believe that open source will make Nyxo more resilient against time. This is the only way the product can outlive it's original creators, and the also the way to do things faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contributing
&lt;/h3&gt;

&lt;p&gt;If you're interested in contributing to this website, you can find the repository for this website at &lt;a href="https://github.com/hello-nyxo/nyxo-website"&gt;here&lt;/a&gt;. All contributions are welcome, and we want contributing to our projects to be a fun and enjoyable experience for everyone. Contributing to Nyxo goes beyond pull requests and coding. We are happy to receive a variety of contributions, including the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Submitting new feature ideas&lt;/li&gt;
&lt;li&gt;Submitting enhancements, designs, or bug fixes&lt;/li&gt;
&lt;li&gt;Reporting bugs or issues&lt;/li&gt;
&lt;li&gt;Blogging. If you're writing about the things we care about: sleeping, science, and technology, we would really love to have you on our blog. We accept previously released blog posts as well.&lt;/li&gt;
&lt;li&gt;Contributing to the coaching materials we provide&lt;/li&gt;
&lt;li&gt;Providing scientific backing to the coaching. If you're a researcher in the area of sleep and/or well-being, we would love to collaborate with you to create more coaching lessons and exercises. We would also love the highlight your research in our blog&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Coming Soon
&lt;/h3&gt;

&lt;p&gt;As mentioned, this is just the first step. In the coming weeks, we are hoping to make the Nyxo mobile apps for Android and iOS open source as well. They're built with React Native, and we are quite proud of some of the things we've been able to achieve with that platform, but there are also things we would like other people to look at. There's no hard deadline for this, but we are hoping to do this before September.&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>Build a Clock Face with SVG in React Native</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Sat, 13 Jun 2020 12:12:19 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/build-a-clock-face-with-svg-in-react-native-3bkg</link>
      <guid>https://dev.to/plahteenlahti/build-a-clock-face-with-svg-in-react-native-3bkg</guid>
      <description>&lt;p&gt;In this article, we are going to look at how to draw a nice-looking analog clock face by using react-native, react-native-svg , and styled-components. The clock is going to tell time, tick, and have support for dark and light themes.&lt;br&gt;
This is based on the work I’ve done on Nyxo, where we should a clock face as the base for showing your sleep data. I’ve been getting some questions on how to create something similar, which is why I wrote this guide to create them yourselves. If you just want to get your hands on the code, &lt;a href="https://github.com/plahteenlahti/HelloClock"&gt;it’s here.&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Let's start by initing a new project. You could very well do this with Expo, but I prefer to use the ejected version of so React Native, so we are going to use the &lt;code&gt;react-native-cli&lt;/code&gt; and the TypeScript example project to get started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx react-native init helloClock  --template react-native-template-typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;after that, let's install the only external library, we need: &lt;code&gt;react-native-svg.&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;react-native-svg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we need to navigate to &lt;code&gt;ios&lt;/code&gt; folder and install required pods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;ios &amp;amp; pod &lt;span class="nb"&gt;install cd&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now run the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;react-native run-ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Folder structure
&lt;/h2&gt;

&lt;p&gt;I'm going to structure the project in the following way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HelloClock
├── index.js
├── App.tsx
├── components
│ ├── Hand.tsx
│ ├── ClockMarkings.tsx
│ └── Clock.tsx
├── helpers
│ ├── geometry.ts
│ ├── time.ts
│ └── useInterval.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Polar and Cartesian Coordinates
&lt;/h2&gt;

&lt;p&gt;Now to the bread and butter of this article so how to convert time to coordinates on SVG.&lt;/p&gt;

&lt;p&gt;We can think of clock times in degrees, i.e., 12 am and 12 pm clock being the same as 0° and 6 pm and 6 am being 180°. We could, of course, use radians as well, but for me, at least degrees feel more familiar. A coordinate system which uses angle and reference point to determine a point on a plane is &lt;a href="https://en.wikipedia.org/wiki/Polar_coordinate_system"&gt;Polar coordinate system&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Converting time to Polar coordinate systems is relatively simple. Let's say we, for example, want to determine the angle of the minute hand on a clock in degrees when we know the number of minutes to be 30. If one full revolution is 60 minutes and one complete revolution is 360°, then dividing 30 minutes with 60 and multiplying that with 360 gives the same number of minutes in degrees, which is 180. Let's implement that with code into the time file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;polarToCartesian&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;centerX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;centerY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;angleInDegrees&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;angleInRadians&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;angleInDegrees&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;180.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;centerX&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;angleInRadians&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;centerY&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;angleInRadians&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building the Clock Component
&lt;/h2&gt;

&lt;p&gt;Let’s start the UI stuff by cleaning up the App.tsx file so that it only has a &lt;code&gt;StatusBar&lt;/code&gt;, &lt;code&gt;SafeAreView&lt;/code&gt; the &lt;code&gt;&amp;lt;Clock&amp;gt;&lt;/code&gt;-component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Clock&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/Clock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components/native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StatusBar&lt;/span&gt; &lt;span class="nx"&gt;barStyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light-content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SafeAreaView&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ScrollView&lt;/span&gt;
          &lt;span class="nx"&gt;centerContent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;contentInsetAdjustmentBehavior&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;automatic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Clock&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ScrollView&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SafeAreaView&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ScrollView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ScrollView&lt;/span&gt;&lt;span class="s2"&gt;`
  flex: 1;
  background-color: black;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SafeAreaView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SafeAreaView&lt;/span&gt;&lt;span class="s2"&gt;`
  background-color: black;
  flex: 1;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StatusBar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StatusBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;barStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;``&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s not save the file just yet, but instead, start working on the Clock, ClockMarks, and Hand components. Import Dimensions from react-native and Svg-component from &lt;code&gt;react-native-svg&lt;/code&gt; and make the Clock return a square SVG with the side of the squares being the same as the width of the mobile phone's screen by using the Dimensions helper:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Clock.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Svg&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;window&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Clock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Svg&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Svg&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Clock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when we save, nothing should appear on the screen. This is because SVG itself has no visible parts. Let’s continue by adding the ClockMarks to communicate the minutes and hours. First, let’s define how many ticks we want. Let’s write those values above the Clock component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Clock.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Svg&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;window&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;window&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;diameter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;diameter&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hourStickCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minuteStickCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Clock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Svg&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Svg&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Clock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don’t want the clock to take the whole space of the screen, so we define the diameter to be the width of the screen minus 40. Then we want the clock to be in the center of the screen, so we divide the width of the screen with 2, and last we also need radius, which is, of course, half of the diameter.&lt;/p&gt;

&lt;p&gt;For hours we want 12. In analog clocks, there are usually five divisions between every hour tick, and that’ How we are going to do it as well. However because because because we will keep the spacing between minute ticks consistent, it means that one of the minutes marking is going to overlap with every hour, we are going to add one extra tick and then multiply that by the number of hours, which equals to 72 minute markings&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Clock Divisions
&lt;/h2&gt;

&lt;p&gt;Not let’s put the values to use by creating the clock face values. Create a new file ClockMarkings.tsx. The ClockMarkings.tsx is going to contain the clock divisions for both hours and minutes. The component is going to accept props for radius, center point, minutes, and hours. Radius and center are going to be used to determine the arc on which the divisions will be placed and hours and minutes are going to tell us how many tics we want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ClockMarkings.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;G&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;polarToCartesian&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../helpers/geometry&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;center&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ClockMarkings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hours&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minutesArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hoursArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minuteSticks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;minutesArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;minute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;polarToCartesian&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;polarToCartesian&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Line&lt;/span&gt;
        &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;strokeLinecap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;x1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;x2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;y1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;y2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hourSticks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hoursArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;polarToCartesian&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;polarToCartesian&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;polarToCartesian&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;G&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Line&lt;/span&gt;
          &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;strokeLinecap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="nx"&gt;x1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;x2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;y1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;y2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;
          &lt;span class="nx"&gt;textAnchor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;middle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="nx"&gt;fontSize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;17&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="nx"&gt;fontWeight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="nx"&gt;alignmentBaseline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;central&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/G&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;G&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;minuteSticks&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;hourSticks&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/G&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ClockMarkings&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use the hours and minutes variables to create arrays that match in length to the division count we want. Then we map those arrays to return Svg lines and make use of the polarToCartesian function we created earlier to the get correct position of the tics on the arc. I also added the Text tag so we can have nice numbers on the clockface. Because the array starts from zero, instead of using the index to render the number, in that case, it switches it with 12, so that our clock has number 12 on the top instead of zero.&lt;/p&gt;

&lt;p&gt;Now if we add the ClockMarkings component to the Clock component and pass the variables for the clock face from earlier, we get something that looks like this:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Creating the Clock Hands
&lt;/h2&gt;

&lt;p&gt;The clock is nothing without the hands so let’s make those next. Create a new component called Hand.tsx in the components folder with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Hand.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Line&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;polarToCartesian&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../helpers/geometry&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;center&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;strokeWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Hand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;strokeWidth&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;polarToCartesian&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Line&lt;/span&gt;
      &lt;span class="nx"&gt;x1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;y1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;x2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;y2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;strokeLinecap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Hand&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This component is a lot simpler than the Clock markings because it’s only a single SVG line. We use the function polarToCartesia from earlier and pass down the angle from Clock.tsx to this component, as well as the strokeWidth and stroke variables which we going to use to make the hands for seconds, minutes, and hours to differ from each other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Svg&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ClockMarkings&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./ClockMarkings&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Hand&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Hand&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useInterval&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../helpers/hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getTime&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../helpers/time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;window&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;diameter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;diameter&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hourStickCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minuteStickCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Clock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTime&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Svg&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ClockMarkings&lt;/span&gt;
        &lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;minuteStickCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;hours&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;hourStickCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hand&lt;/span&gt;
        &lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hand&lt;/span&gt;
        &lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hand&lt;/span&gt;
        &lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;7&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Svg&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Clock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could now use this component to make a clock look like something in the picture below. However, because our clock hands don’t accept time yet, you would need to calculate the correct angle for the time you want to display. So let’s continue by creating a couple of helper functions that will allow us to turn time values into coordinates for our clock.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// time.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;to12hClock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;hour&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;hour&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;TimeObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;TimeObject&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;to12hClock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getHours&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMinutes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSeconds&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s go over what the functions do. The to12hClock function is just a small helper to convert 24 -hour clock to 12-clock when getting the hours with the getHours function of JavaScript Date. The getTime function is also quite straight forward. Each time the function is called it creates a new Date object and then uses the native time functions and simple mathematics to convert those to degrees.&lt;/p&gt;

&lt;p&gt;Let’s also create a new useInterval hook, that we can then use to periodically create new time for our clock. Here’s the code for it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// useInterval.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// From Dan Abramov https://overreacted.io/making-setinterval-declarative-with-react-hooks/&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;savedCallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Remember the latest callback.&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;savedCallback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="c1"&gt;// Set up the interval.&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;savedCallback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the clock component to use our new getTime function with the useInterval and useState hooks and we ourselves a clock that ticks!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Clock.tsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Svg&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ClockMarkings&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./ClockMarkings&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Hand&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Hand&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useInterval&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../helpers/hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getTime&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../helpers/time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;window&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;diameter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;diameter&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hourStickCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minuteStickCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Clock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTime&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Svg&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ClockMarkings&lt;/span&gt;
        &lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;minuteStickCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;hours&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;hourStickCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hand&lt;/span&gt;
        &lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hand&lt;/span&gt;
        &lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hand&lt;/span&gt;
        &lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;7&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Svg&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Clock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Theming the Clock
&lt;/h2&gt;

&lt;p&gt;Supporting a dark mode is almost a must these days. So let’s stylize our clock a little and add a dark mode.&lt;/p&gt;

&lt;p&gt;Let’s start by creating a themes.ts file in the root of the project and with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;themes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DefaultTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components/native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;DefaultTheme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;bgColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;primaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;secondaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;accentColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lightTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DefaultTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;bgColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;primaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#333&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;secondaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#555&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;accentColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#4a5aef&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;darkTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DefaultTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;bgColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#111&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;primaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;secondaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#CACACA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;accentColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#4aefd5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’m going to use four colors in this case. To get TypeScript support, I made a custom theme declaration. If you want to learn more about that, &lt;a href="https://www.lahteenlahti.com/styled-components-theming-with-typescript/"&gt;I have written about it earlier here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then we need to convert some of our existing components to use those theme variables instead of the previously set colors. This is what it should look like in the App.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.tsx&lt;/span&gt;
&lt;span class="c1"&gt;//...ealier App.tsx code&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ScrollView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ScrollView&lt;/span&gt;&lt;span class="s2"&gt;`
  flex: 1;
  background-color: &lt;/span&gt;&lt;span class="p"&gt;${({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bgColor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SafeAreaView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SafeAreaView&lt;/span&gt;&lt;span class="s2"&gt;`
  background-color: &lt;/span&gt;&lt;span class="p"&gt;${({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bgColor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
  flex: 1;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StatusBar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StatusBar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;barStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;``&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s also change the styling of the clock markings and the clock hands so that with the dark theme we change the stroke and fill colors in the following way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ClockMarkings.ts&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Minute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Line&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secondaryColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;``&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HourLine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Line&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secondaryColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;``&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HourNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primaryColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;``&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Clock.ts&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Hand&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accentColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;strokeOpacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;``&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Hand&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primaryColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;strokeOpacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;``&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Hours&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Hand&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primaryColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;strokeOpacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;&lt;span class="s2"&gt;``&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will need to change the props on the Hand component so that the stroke and strokeOpacity are passed down to the underlying SVG component. You can find the full code on how that is done here.&lt;/p&gt;

&lt;h2&gt;
  
  
  End Result
&lt;/h2&gt;

&lt;p&gt;Now you should have a ticking clock that respects the user’s preferred theme. If you wanted to improve this, you could animate the hand movements.&lt;/p&gt;

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

</description>
      <category>reactnative</category>
      <category>svg</category>
    </item>
    <item>
      <title>Static Sites in Swift: Getting Started With Publish</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Fri, 22 May 2020 17:24:28 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/static-sites-in-swift-getting-started-with-publish-1em3</link>
      <guid>https://dev.to/plahteenlahti/static-sites-in-swift-getting-started-with-publish-1em3</guid>
      <description>&lt;p&gt;A few days ago, I accidentally stumbled upon &lt;a href="https://github.com/JohnSundell/Publish"&gt;Publish&lt;/a&gt;, a static site generator that uses Swift as the language for building websites. Despite not being a Swift developer, I thought this sounded quite awesome. So I decided to try if the time I've spent playing around with SwiftUI could be enough to get up and running with a static site built with Swift.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Use Swift and Publish?
&lt;/h3&gt;

&lt;p&gt;Just because something is cool, does mean it's worth doing, and the same applies to building static websites with random languages. Now Swift is hardly a random language. Most people might know it as the "Apple's programming language", and building iOS and macOS apps is what it's mostly used for. However, a lot more has been accomplished with Swift in recent years, after Apple open sourced the language. One of these areas where there's quite a lot of Swift usage is server-side, and a lot of cool &lt;a href="https://github.com/Awesome-Server-Side-Swift/TheList"&gt;server-side projects have already been built with Swift&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Being a mostly React and React Native engineer, I'm not the best person to talk about why use Swift to build stuff, having used it so little myself and not knowing all the pros and cons of the language. But let's just say that even from an outsider's perspective, Swift is a pretty good programming language. It has the usual perks of being a modern language, meaning that it borrows a lot of concepts from existing languages which makes it easier to pick up. On top of that, it also seems to be quite a performant language (&lt;a href="http://www.marcinkliks.pl/2015/02/22/swift-vs-others/"&gt;based on this slightly old, slightly arbitrary benchmark&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;What about Publish then? What makes it good? Looking at the repo and some of the examples sites built with it, it seems that Publish really excels in being quick to get started with, but still allowing you to tweak many things. The basic Publish setup for example comes with RSS, Markdown support, and sitemap, which the most important parts for building a static site. It also supports themes, which you write in Swift using something called &lt;a href="https://github.com/johnsundell/plot"&gt;Plot&lt;/a&gt;, an HTML theming engine from the same author as Publish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing the command line tools
&lt;/h2&gt;

&lt;p&gt;Let's start by installing the command line tools by cloning the Publish repository and then running &lt;code&gt;make&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone https://github.com/JohnSundell/Publish.git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;Publish
&lt;span class="nv"&gt;$ &lt;/span&gt;make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're not that familiar with the &lt;code&gt;make&lt;/code&gt; command, it's a part of Make build automation tool that automatically builds programs and libraries from the source code. In order to use make command you need to have Apple developer tools installed. You can install them by running :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;xcode-select &lt;span class="nt"&gt;--install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now have the Publish command line tools installed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a New Project With Publish
&lt;/h2&gt;

&lt;p&gt;Let's continue out by making a new directory for our project, navigating to it, and then running publish new&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;swift.lahteenlahti.com
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;swift.lahteenlahti.com
&lt;span class="nv"&gt;$ &lt;/span&gt;publish new
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this a new Publish project will be initialized for you. You can open the Package.swift file in Xcode if you want to use that for development, or you can use something VS code. Let's look at what makes up our new static website:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|-- swift.lahteenlahti.com
|   |-- Content
|       |-- posts
|       |-- index.md
|   |-- Resources
|   |-- Sources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sources&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
In this folder you can find your project's main.swift file, which defines some of the basic properties of your website, such as name, language, URL and description. We are going to look at customizing your Publish site in a separate post, so let's leave this file untouched for now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
In the content folder you can find your content in markdown format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This folder is empty for now but is later used for theming the project. In the Publish repository you can see that it contains the default FoundationTheme's styles.css file.&lt;/p&gt;
&lt;h2&gt;
  
  
  Building the Site
&lt;/h2&gt;

&lt;p&gt;To turn all these files into a static website you need to build the project, which you can do by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;publish run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this you see the Output folder being generated and Publish init a Simple PHP server to serve your site to localhost:8000. If you go that address, you should now see your site. Cool!&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing to Netlify
&lt;/h2&gt;

&lt;p&gt;One of the coolest things with static websites nowadays is how easy it is to publish them. Just put your code in Github or Gitlab repository, give Vercel or Netlify access to the repository, and done. I've been using both Netlify and Vercel (haven't yet had a chance to try Gatsby Cloud) to publish my sites, most of which have been built with Gatsby, and they support a variety of different static site generators. But how about something built with Swift?&lt;/p&gt;

&lt;p&gt;You could always run the build command on your own computer, and make Netlify serve the already static stuff, but this would kind of defeat the purpose of using a deployment service such as Netlify. However, it turns out that &lt;a href="https://github.com/netlify/build-image/pull/364"&gt;Netlify has support for Swift&lt;/a&gt;. Let's make our static blog see the outside world by publishing it with Netlify.&lt;/p&gt;

&lt;p&gt;First, signup for a Netlify account if you don't already have one, and next make a new Github or Gitlab repository and allow Netlify to use that. I would also add the Output folder to gitignore. After this you only have to configure the build settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Publish Directory&lt;/code&gt; should be &lt;code&gt;Output&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Build Command&lt;/code&gt; should be &lt;code&gt;swift run&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's literally it! if you now go the URL provided by Netlify, you should soon see your blog there.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;I'm personally trying to move towards more native development, so playing around Swift in a context that I'm more familiar with (web) is one way to build on top of existing knowledge. The Publish project we made in this quick tutorial is something I'm going to use to keep track of my upcoming 100daysofSwiftUI journey. In future articles, I'm going to look at how style your Publish blog, and how to add stuff like code snippets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/JohnSundell/Publish"&gt;Publish&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://netlify.com"&gt;Netlify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.apple.com/swift/"&gt;Swift&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/plahteenlahti/swifting"&gt;My example repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>swift</category>
      <category>netlify</category>
      <category>publish</category>
    </item>
    <item>
      <title>TypeScript Configuration For styled-components In React Native</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Sun, 10 May 2020 14:09:14 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/typescript-configuration-for-styled-components-in-react-native-237</link>
      <guid>https://dev.to/plahteenlahti/typescript-configuration-for-styled-components-in-react-native-237</guid>
      <description>&lt;p&gt;Using &lt;a href="https://styled-components.com/"&gt;Styled-components&lt;/a&gt; with React Native is great. Where it really shines in my opinion is theming. However, wouldn't it be cool if you get type-checking for the themes you've created, as well as auto-complete for the theme variables? So that when you're writing something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="s2"&gt;`
  color: &lt;/span&gt;&lt;span class="p"&gt;${({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primaryColor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you wouldn't have to remember if whether the primary color was written as &lt;code&gt;primaryColor&lt;/code&gt; or &lt;code&gt;primary_color&lt;/code&gt;, Instead your editor tells you what theme variables stored inside the theme object you've created.&lt;/p&gt;

&lt;p&gt;Well good news, you can easily achieve this by using the Typescript interface merging to override the default theme that comes with styled-components (more info how declaration merging works can be found &lt;a href="https://www.typescriptlang.org/docs/handbook/declaration-merging.html"&gt;here&lt;/a&gt;, and &lt;a href="https://styled-components.com/docs/api#create-a-declarations-file"&gt;here&lt;/a&gt;). Here's how to achieve that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To access the theme in our app, we need to first setup ThemeProvider and the pass down our custom theme inside it.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components/native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Navigation&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lightTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/styles/theme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;lightTheme&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Navigation&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ThemeProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;We create the theme file and merge the declaration of DefaultTheme provided by styled-components with our own definition. Then we tell our themes to use that interface.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// theme.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DefaultTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components/native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;DefaultTheme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;primaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lightTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DefaultTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;primaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;333&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;secondaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;666&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;darkTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DefaultTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;primaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;secondaryColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;cacaca&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  That's it
&lt;/h2&gt;

&lt;p&gt;Now every time you use the theme variables it comes equipped with TypeScript's typing powers. Even better, if you're using for example VS Code, it automatically provides you with auto-completion for the theme variables.&lt;/p&gt;

</description>
      <category>styledcomponents</category>
      <category>typescript</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>How to Fix 'VirtualizedLists should never be nested inside plain ScrollViews' Warning</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Thu, 20 Feb 2020 17:04:42 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/how-to-fix-virtualizedlists-should-never-be-nested-inside-plain-scrollviews-warning-4f7e</link>
      <guid>https://dev.to/plahteenlahti/how-to-fix-virtualizedlists-should-never-be-nested-inside-plain-scrollviews-warning-4f7e</guid>
      <description>&lt;p&gt;When developing with React Native and nesting FlatList or SectionList component inside a plain ScrollView your debugger might display the following warning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;VirtualizedLists should never be nested inside plain ScrollViews with the same orientation
- use another VirtualizedList-backed container instead.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This warning pretty much tells what is about. What is doesn't tell, is why this is bad and how to fix warning (other than changing the orientation of the nested VirtualizedList but that is not always possible). Let's look at how why this happens and how to fix it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why nesting VirtualizedList inside a plain ScrollView is bad?
&lt;/h3&gt;

&lt;p&gt;Virtualized lists, which means  and  are performance-optimized which massively improves memory consumption and performance when using them to render large lists of content. The way this optimization works is that it only renders the content that is currently visible in the window, usually meaning the container/screen of your device. It also replaces all the other list items same sized blank space and renders them based on your scrolling position.&lt;/p&gt;

&lt;p&gt;Now If you put either of these two lists inside a ScrollView they fail to calculate the size of the current window and will instead try to render everything, possibly causing performance problems, and it will of course also give you the warning mentioned before.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to fix this warning the right way
&lt;/h3&gt;

&lt;p&gt;The fix to this warning is simpler than you think: get rid of the ScrollView, and place all the components that surround the FlatList inside ListFooterComponent and ListHeaderComponent.&lt;/p&gt;

&lt;p&gt;Let's see how this works in practice. In this example, we have an app where the user can scroll through different recipes. The main view consists of a ScrollView and inside that view, we have a collection of components such as a header, a footer, some text, and a cover photo. It looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CoverPhoto&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Take a look at the list of recipes below:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Footer&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Now say we want to list all the recipes under last Text element using FlatList after which it would look something like this:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderItem&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Recipe&lt;/span&gt;
      &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;recipe&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    )
  }

  return (
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CoverPhoto&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Take a look at the list of recipes below:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FlatList&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;recipes&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;renderItem&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;renderItem&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Footer&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ScrollView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;This will then, of course, give you the warning that was mentioned before, and you will also not be able to use the performance features FlatList has. That is why we are going to get rid of the ScrollView completely and instead use the ListFooterComponent and ListHeaderComponent props like so:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderItem&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Recipe&lt;/span&gt;
      &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;recipe&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    )
  }

  return (
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FlatList&lt;/span&gt;
      &lt;span class="na"&gt;LisHeaderComponent&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CoverPhoto&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Take a look at the list of recipes below:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;recipes&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;renderItem&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;renderItem&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;ListFooterComponent&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Footer&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Both props only accept one component so we wrapped the components in the ListHeaderComponent with Fragments. But there you have it, no more warnings and everything still looks the same.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared on my &lt;a href="https://www.lahteenlahti.com/fixing-virtualizedlists-should-never-be-nested-inside-plain-scrollviews/"&gt;personal blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>mobiledevelopment</category>
    </item>
    <item>
      <title>Successful Rapid Prototyping With React Native</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Sun, 29 Dec 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/successful-rapid-prototyping-with-react-native-54l7</link>
      <guid>https://dev.to/plahteenlahti/successful-rapid-prototyping-with-react-native-54l7</guid>
      <description>&lt;p&gt;This is a transcript of a lightning talk I gave at React Day Berlin in 2019. You can watch the talk &lt;a href="https://www.youtube.com/embed/QafikEOSUGA"&gt;here&lt;/a&gt;, and download the presentation slides &lt;a href="https://www.lahteenlahti.com/2108a3140b2c06b0ea53566dc81904c5/ReactDayBerlin19.pdf"&gt;here&lt;/a&gt;. All the links and resources are available at the end of this transcript. This post originally appeared on my &lt;a href="https://www.lahteenlahti.com/successful-rapid-prototyping-with-react-native/"&gt;personal blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But before we go into all that, I want to give a little introduction to myself. So the reason for my complicated name "Perttu Lähteenlahti" is because I'm from Finland, which is by the way celebrating its Independence Day today. I'm a developer/designer at a company called Nyxo, where we build personalized sleep coaching programs in a mobile app format.&lt;/p&gt;

&lt;p&gt;The reason I know a lot about prototypes is because I've taken part in around 70 hackathons, which are, in a way, prototyping competitions. I've won about 40 of those, so I've been moderately successful.&lt;/p&gt;

&lt;p&gt;But let's get to the subject at hand, so why prototype? Reasons for doing that could be simply that:&lt;br&gt;
You're starting from scratch&lt;br&gt;
You want to try out new technology&lt;br&gt;
You're unsure of the path the product is going to take&lt;br&gt;
Generally speaking, prototyping is something you do every time you're unsure what you're supposed to do. That's precisely the place where I started about a year ago when I was hired by two university research to commercialize their sleep research. I went to the first meeting, and the conversation went a little like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Researchers:&lt;/strong&gt; &lt;em&gt;"build us a product."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; &lt;em&gt;"can you be more specific?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Researchers:&lt;/strong&gt; &lt;em&gt;"build as a product that is nice to use and makes money."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I was like that doesn't make it any more apparent, but then I decided that I might as well start by building a prototype.&lt;/p&gt;

&lt;p&gt;I ended up building these three prototypes. In the one you see on the left of the picture, we decided to experiment with how people would like to see their sleep data. What kind of presentation types work and which do not.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dRHyFTD8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.lahteenlahti.com/static/6cb5dc7835e521bcd97c943ad938ddf7/6b690/prototypes.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dRHyFTD8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.lahteenlahti.com/static/6cb5dc7835e521bcd97c943ad938ddf7/6b690/prototypes.png" alt="Three prototypes I build." width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the middle one, we tested out how you should provide sleep coaching content, which means, e.g., how to show exercises and lessons that are engaging and interesting to go through.&lt;/p&gt;

&lt;p&gt;And on the right one, we tested that if you could make sleeping into a game so every night you would try to sleep better than your friends and that way compete against your friends.&lt;/p&gt;

&lt;p&gt;When I was researching how to build these prototypes, I had one hard requirement: I have able to take part in the coding as well. Because I have a background in design and web development, native iOS or Android weren't a viable option. React Native turned out to be a kind of a perfect solution for that. But not just because it's suitable for prototyping but because I could also use it to build the end product. This transition is possible because building with React Native is relatively straightforward to build with it. It's also really fast to build with it, and it's even faster to deliver and measure everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building
&lt;/h2&gt;

&lt;p&gt;Let's look at why is building apps with React Native is so swift. For starters, the are many great UI kits such as react-native-paper. I like to build UIs myself. Mainly because I will then know how every component is built, and can then use them more effectively. In general, React Native allows you to build cool stuff fast just because you can employ your existing skills from React and JavaScript so much.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delivering
&lt;/h2&gt;

&lt;p&gt;What is maybe even cooler is delivering fast. React Native's capability to deliver fast actually saved our butts when we were testing one of our pilot products with the largest life insurance company in Finland. One Friday I got an email that said:&lt;/p&gt;

&lt;p&gt;"hey, this feature we agreed on doesn't work for me."&lt;/p&gt;

&lt;p&gt;Reading that email, I was like we never agreed on that feature. It was never supposed to be in this pilot. However, instead of arguing over email, I instead decided to try if I could fix things without anyone noticing. So during the weekend, I built the feature and released it before Monday. Without React Native that would not have been possible, because the usual way you do it through App Store connect and Play Store is really painful it takes many days for Apple to look at but using Codepush we were able to update the code. The users didn't even notice that the feature was missing. The following Monday I got an email saying "sorry it might have been my device that it didn't work."&lt;/p&gt;

&lt;p&gt;Expo is a pretty good solution, also offering you the same capabilities of pushing your code over-the-air as CodePush.&lt;/p&gt;

&lt;p&gt;Last but not least, there's also react-native-remote-config that is part of React Native Firebase. It isn't as powerful as Codepush or Expo, but still allows you to make changes on the fly, but only in the configuration as you can change the JavaScript bundle by using this. It is still worth considering, especially if you're already using Firebase in your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analytics
&lt;/h2&gt;

&lt;p&gt;Before becoming a product designer/developer, I was a carpenter for seven years. There we used the mantra "measure twice" a lot. However, when I transitioned to the technology world, this mantra turned into a "measure everything". Measure what the user is doing, how long they are doing it, and what they are doing. Because in prototyping, your progress is only as good as results and feedback you get you. To do that, use the following tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amplify analytics from AWS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Firebase Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App Center Analytics (we use this mostly)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is also one hack that reveals some hidden user behavior. Wrap all the components with different  components and make them emit and analytics event when the user clicks them. It allows you to understand which parts of the screen users are pressing, and for example, reveals if they consider something to be clickable that is not. In our case, it showed both UX problems as well and potential new features. However, please don't do this in production; it's terrible for accessibility.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VEQJkW4l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.lahteenlahti.com/static/138c9827eb8ee3ff5c0874d04ea8a9df/6b690/hack.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VEQJkW4l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.lahteenlahti.com/static/138c9827eb8ee3ff5c0874d04ea8a9df/6b690/hack.png" alt="Screenshot of the presentation with an analytics hack " width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This concludes my lightning talk on Successful rapid prototyping.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build fast with

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://reactnativepaper.com/"&gt;React Native Paper&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Deliver fast

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://expo.io"&gt;Expo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Microsoft/code-push"&gt;CodePush&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://invertase.io/oss/react-native-firebase/v6/remote-config"&gt;Remote Config&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Measure everything.

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws-amplify.github.io/"&gt;AWS Amplify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appcenter.m"&gt;App Center&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rnfirebase.io/docs/v5.x.x/analytics/ios"&gt;Firebase&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared on my &lt;a href="https://www.lahteenlahti.com/successful-rapid-prototyping-with-react-native/"&gt;personal blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>ios</category>
    </item>
    <item>
      <title>Checklist for releasing React Native apps</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Thu, 31 Oct 2019 09:34:02 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/checklist-for-releasing-react-native-apps-dhf</link>
      <guid>https://dev.to/plahteenlahti/checklist-for-releasing-react-native-apps-dhf</guid>
      <description>&lt;h2&gt;
  
  
  Releasing to App store
&lt;/h2&gt;

&lt;p&gt;Getting your mobile app published in the App Store is simple in theory but tedious in practice. During the past nine months, I've sent several versions of the Nyxo app to be reviewed by Apple. Almost every time Apple has rejected a new version of the app, it has been because of some minor thing. That is why I decided to write a checklist for releasing your app to the App Store. Many of the items on this checklist can be automated using, for example, Fastlane, something I will write a separate setup guide and checklist later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before bundling the app
&lt;/h2&gt;

&lt;p&gt;Increment the build number or number version&lt;br&gt;
Because archiving the app takes some time, it's better to check this every time you start the archiving process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check the app for crashes and bugs

&lt;ul&gt;
&lt;li&gt;Apple is, at times, very thorough in their app review. Check especially that your app works on iPad, even if you don't plan to support the device that is the device Apple uses for testing&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;No broken links

&lt;ul&gt;
&lt;li&gt;If you're linking to content outside of your app, check that those links also work as Apple rarely checks them as well.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Remove placeholder content&lt;/li&gt;
&lt;li&gt;Check that your app doesn't mention 'beta' or any other words that could signal that the app is incomplete

&lt;ul&gt;
&lt;li&gt;Apple is very strict about this. Remember to also check everything&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Check permissions

&lt;ul&gt;
&lt;li&gt;Check that your info.plist includes all the permissions your app requires.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Check localizations and translations

&lt;ul&gt;
&lt;li&gt;Check that you're not missing any translation key/values. Apple only tests the English version&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Things to check in App Store Connect
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Check app name and localizations

&lt;ul&gt;
&lt;li&gt;Check this especially if you've recently changed the name of the app in App store in any way&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Check keywords and keyword localizations

&lt;ul&gt;
&lt;li&gt;It is good to update the keywords periodically, as it can potentially boost your App store search hits a lot.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Check in-app purchase sections

&lt;ul&gt;
&lt;li&gt;Check the names and descriptions of your in-app purchases&lt;/li&gt;
&lt;li&gt;If you're offering subscriptions, remember to check that your app description contains a mention of these and the prices; otherwise, Apple will reject your app&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Check that your screenshots are up to date

&lt;ul&gt;
&lt;li&gt;If you've updated the UI of your app, always update the App Store screenshots as well.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Check you app description text

&lt;ul&gt;
&lt;li&gt;Pay attention to the "text above the fold." Because the user has to click to expand it to see the rest of it.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Check that your update text is compelling

&lt;ul&gt;
&lt;li&gt;"What's new" is one of the first things users see when they open your app's product page, which is why it's essential to make it highlight all the new features you added in this release.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  After releasing the app
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Notify users that you've updated the app

&lt;ul&gt;
&lt;li&gt;I like to automate this part with IFTTT, which allows you to for example automatically tweet when the new version your app has been released&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Post to your channels and ask them to download/update to a new version of your app

&lt;ul&gt;
&lt;li&gt;Downloading the app can boost its position on Apple's chart, which is always good - Also don't be too shy to ask the people to know to rate your app, as it will improve its position in the Apple search&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Prepare for the next release

&lt;ul&gt;
&lt;li&gt;Ship early, ship often&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the main things I check with every release. If you feel something should be included, leave a comment. You can also make you use of the checklist tool I've built for this, which allows you to actually check all the items on the list. You can find that &lt;a href="https://perttu.dev/checklist"&gt;here&lt;/a&gt;. I will write a similar checklist for the Google Play Store, as well. However, I will first need to get to know it better.&lt;/p&gt;

&lt;p&gt;This post originally appeared on my dev blog &lt;a href="https://perttu.dev"&gt;perttu.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Running React Native apps on specific iOS simulators</title>
      <dc:creator>👨‍💻 Perttu Lähteenlahti</dc:creator>
      <pubDate>Thu, 31 Oct 2019 09:13:42 +0000</pubDate>
      <link>https://dev.to/plahteenlahti/running-react-native-apps-on-specific-ios-simulators-5c7b</link>
      <guid>https://dev.to/plahteenlahti/running-react-native-apps-on-specific-ios-simulators-5c7b</guid>
      <description>&lt;p&gt;Testing your app on multiple devices and screen sizes is a must. Luckily React Native makes this relatively quick to do. If you're developing React Native apps for iOS you're most likely familiar with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;react-native run-ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In most cases, that command opens up the iPhone X simulator. Instead, if you want to open your React Native app in a specific simulator you can also add the wanted device name with the simulator flag like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;react-native run-ios &lt;span class="nv"&gt;simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'iPhone 8'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it will open up the iPhone 8 Simulator. You can get the full list of available devices with the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xcrun simctl list devices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here's a list of all the available devices available for testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 5s"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 6"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 6 Plus"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 6s"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 6s Plus"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 7"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 7 Plus"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 8"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 8 Plus"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone SE"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone X"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone XR"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone XS"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone XS Max"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 11"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 11 Pro"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone 11 Pro Max"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPhone XS Max"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPad Air"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPad Air 2"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPad"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPad Pro"&lt;/span&gt;
react-native run-ios &lt;span class="nt"&gt;--simulator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"iPad"&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  I'm getting "Could not find iPhone X simulator" or similar error message when running this command
&lt;/h3&gt;

&lt;p&gt;At times you might run into problems with this command. This error message, for example, is quite common:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Could not find iPhone X simulator

Error: Could not find iPhone X simulator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This error is often caused by updating to a new Xcode version, which doesn't include the iPhone X simulator any more, which is the default for react-native-cli. This problem should disappear when you pass the simulator flag and another device than iPhone X.&lt;/p&gt;

&lt;p&gt;This was a quick and simple guide to running on different iOS simulators when building React Native apps. I wrote this because I found myself googling different device names too often. I hope that you find it useful. 🙂&lt;/p&gt;




&lt;p&gt;This post originally appeared on my dev blog &lt;a href="https://perttu.dev"&gt;perttu.dev&lt;/a&gt;&lt;/p&gt;

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