<?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: Daniel Koprowski</title>
    <description>The latest articles on DEV Community by Daniel Koprowski (@koprowski_it).</description>
    <link>https://dev.to/koprowski_it</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%2F370190%2Fe01c5af1-e582-4a51-9167-f855a88f2242.jpg</url>
      <title>DEV Community: Daniel Koprowski</title>
      <link>https://dev.to/koprowski_it</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/koprowski_it"/>
    <language>en</language>
    <item>
      <title>Coding in Quiet: How I Solved Slack Noise as a Developer</title>
      <dc:creator>Daniel Koprowski</dc:creator>
      <pubDate>Sun, 21 Apr 2024 00:00:00 +0000</pubDate>
      <link>https://dev.to/koprowski_it/coding-in-quiet-how-i-solved-slack-noise-as-a-developer-3n7p</link>
      <guid>https://dev.to/koprowski_it/coding-in-quiet-how-i-solved-slack-noise-as-a-developer-3n7p</guid>
      <description>&lt;p&gt;In today's fast-moving tech environment, staying focused is a significant challenge for developers like you and me. Between constant emails, messages, and notifications, it's easy to lose track of what we're working on.&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%2Fwww.progractivity.com%2Fassets%2Fimages%2F07-notifications-noise-610fca3a96a4d73e2d7a8e368635b90c.webp" 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%2Fwww.progractivity.com%2Fassets%2Fimages%2F07-notifications-noise-610fca3a96a4d73e2d7a8e368635b90c.webp" alt="Notifications noise illustration" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This blog post is for developers who struggle to maintain their concentration amid all these distractions. I'll share stories that might feel familiar and offer straightforward advice on reducing distractions to focus better on our work.&lt;/p&gt;

&lt;p&gt;I'll share my journey on staying connected without sacrificing my precious deep work time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slack: My Biggest Distraction&lt;a href="https://www.progractivity.com/flow/coding-in-quiet-how-i-solved-slack-noise-as-a-developer/#slack-my-biggest-distraction" rel="noopener noreferrer"&gt;​&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;My average day used to be interrupted by Slack notifications all the time. This made it hard to do any deep, focused work. Chat apps are supposed to help us communicate, but instead, they often make me feel like I need to reply right away. This can take up most of my day, leaving little time for the work I actually need to do.&lt;/p&gt;

&lt;h3&gt;
  
  
  Foundational Step: Establishing Expectations for Asynchronous Communication on Slack&lt;a href="https://www.progractivity.com/flow/coding-in-quiet-how-i-solved-slack-noise-as-a-developer/#foundational-step-establishing-expectations-for-asynchronous-communication-on-slack" rel="noopener noreferrer"&gt;​&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Recognizing the severity of this issue, I started by setting clear expectations with my team: &lt;strong&gt;Slack is for asynchronous communication, not a hotline to my immediate attention.&lt;/strong&gt; This understanding is vital for the effectiveness of any further actions.&lt;/p&gt;

&lt;p&gt;Keep in mind that this has to be done openly. Some people are used to instant replies and might get the wrong idea of why you're silent while "active." The most straightforward tool to inform them is to set up a proper status icon and description.&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%2Fwww.progractivity.com%2Fassets%2Fimages%2F07-focus-time-slack-status-fa4cbfa282369c3f1826764963a16b79.webp" 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%2Fwww.progractivity.com%2Fassets%2Fimages%2F07-focus-time-slack-status-fa4cbfa282369c3f1826764963a16b79.webp" alt="Setting Slack status to focus time" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adjusting Notification Settings for Maximum Focus&lt;a href="https://www.progractivity.com/flow/coding-in-quiet-how-i-solved-slack-noise-as-a-developer/#adjusting-notification-settings-for-maximum-focus" rel="noopener noreferrer"&gt;​&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Understanding the primary function of each communication tool is key. Once that's established, it's crucial to customize the notification settings to minimize distractions.&lt;/p&gt;

&lt;p&gt;Here’s how I fine-tune mine for better focus:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Selective Notifications:&lt;/strong&gt; I set Slack to alert me only for direct messages and mentions. This filters out the noise, allowing me to pay attention to what really matters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Silent Alerts:&lt;/strong&gt; I disable sound for all notifications. The visual indicator of notification is there if I take a moment to glance, ensuring I don’t miss anything critical without constant sound interruption.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slack Notifications on Mobile:&lt;/strong&gt; I turn these off completely. This ensures my phone doesn’t pull me away from deep work sessions. When I grab my phone, it can lead to accidental doomscrolling pretty quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick Win: Silent Slack Notifications&lt;a href="https://www.progractivity.com/flow/coding-in-quiet-how-i-solved-slack-noise-as-a-developer/#quick-win-silent-slack-notifications" rel="noopener noreferrer"&gt;​&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;One surprisingly effective change I made was to turn off sound notifications for Slack. I still get the push notifications but without any sound. This minor tweak has made a big difference.&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%2Fwww.progractivity.com%2Fassets%2Fimages%2F07-silent-notifications-f0154a371ab6008f7812f8da08ef50f0.webp" 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%2Fwww.progractivity.com%2Fassets%2Fimages%2F07-silent-notifications-f0154a371ab6008f7812f8da08ef50f0.webp" alt="Silent Slack notifications" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How It Works:&lt;/strong&gt; When I'm coding and deeply focused, I usually don't even notice the silent notifications popping up, which is great—it means I'm not pulled away from my work. If something urgent comes up, I'll see the red dot on the app during my next scheduled break or when I naturally shift tasks, which is usually within the next hour. This way, I don't disrupt the flow of communication with my team, but I also don't let it interrupt my focus.&lt;/p&gt;

&lt;p&gt;This approach has been a game-changer. By removing the immediate, reflexive need to check Slack at every ding, I've found more peace and productivity in my workdays. It's a simple step that any developer can implement right away, and it's helped me balance the need for team communication with my need for uninterrupted coding time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embracing Slack Reminders for Future Tasks&lt;a href="https://www.progractivity.com/flow/coding-in-quiet-how-i-solved-slack-noise-as-a-developer/#embracing-slack-reminders-for-future-tasks" rel="noopener noreferrer"&gt;​&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; Even with less aggressive notification settings, navigating the digital workplace means constantly dealing with incoming messages that require action. While not all demand immediate attention, ignoring them isn't an option either. I've discovered a strategy that allows me to maintain focus on my immediate tasks while ensuring nothing slips through the cracks.&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%2Fwww.progractivity.com%2Fassets%2Fimages%2F07-slack-reminders-805ab57106933185b426038ef64d1dbf.webp" 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%2Fwww.progractivity.com%2Fassets%2Fimages%2F07-slack-reminders-805ab57106933185b426038ef64d1dbf.webp" alt="Slack Reminders illustration" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What?&lt;/strong&gt; My go-to solution is utilizing Slack's reminder feature. I use it a lot. It enables me to earmark important tasks for later attention, recognizing their importance without allowing them to interrupt my current focus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt; Integrating reminders into my daily routine involves a few key steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set Reminders:&lt;/strong&gt; Upon receiving an important but non-urgent task, I immediately set a reminder for it in Slack. I don't even need to set the deadline, I can click "Save for later".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utilize the "Later" Section:&lt;/strong&gt; These reminded tasks are then automatically sorted into the "Later" section. This acts as my personalized to-do list, which I can attend to at the right time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible Review:&lt;/strong&gt; Instead of scheduling specific times, I review the "Later" section when I take a break from current tasks or in between meetings, during times reserved for "shallow" work. This flexible approach ensures that I address these tasks without detracting from periods of deep concentration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimizes Task Switching:&lt;/strong&gt; By employing reminders, I stay engaged with my current work, avoiding the mental strain associated with frequent task switching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guarantees Task Completion:&lt;/strong&gt; Reminders give me the confidence that no critical task will be overlooked, freeing me to concentrate fully on the task at hand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Organizes Tasks Effectively:&lt;/strong&gt; The "Later" section serves as a centralized hub for tasks awaiting my attention, keeping them organized and ready for when I'm available to tackle them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With reminders, every significant task is taken care of in due course, allowing me to remain focused and efficient on my current projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adopt Async Communication with the Unreads View&lt;a href="https://www.progractivity.com/flow/coding-in-quiet-how-i-solved-slack-noise-as-a-developer/#adopt-async-communication-with-the-unreads-view" rel="noopener noreferrer"&gt;​&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; In chat-like apps, I always feel the &lt;em&gt;Fear Of Missing Out&lt;/em&gt; (FOMO) when I don't answer immediately. Clicking in a friend's name or channel on Slack will turn it to a "read" state so I feel the obligation to actually read through - even when I'm busy with other tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What?&lt;/strong&gt; There is a special view, though which allows you to peek at those messages. From this view, we can decide if it is important enough to keep it as "unread" or just mark it as "read" and not bother with this message anymore. It looks a little bit like an email client where, on the left, we see everything that isn't been read yet, and we can go through those messages quickly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt; This view might not be enabled by default in your Slack environment. Here are instructions on how to enable the Unreads view:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click your profile picture in the sidebar.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fslack-imgs.com%2F%3Fc%3D1%26url%3Dhttps%253A%252F%252Fslack.zendesk.com%252Fhc%252Farticle_attachments%252F21332974684563" alt="Static image of a cursor clicking the profile picture menu in the Slack app" width="1920" height="1080"&gt;&lt;em&gt;(image from &lt;a href="https://slack.com/" rel="noopener noreferrer"&gt;Slack.com&lt;/a&gt;)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Preferences&lt;/strong&gt; from the menu.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Home&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Always show in the sidebar&lt;/strong&gt; , check the box next to the "Unreads" item.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What if?&lt;/strong&gt; The usability of this view grows even more thanks to the support of good keyboard shortcuts. I navigate with arrows and mark some as "read" using the &lt;code&gt;Esc&lt;/code&gt; key. More about shortcuts and mobile features of this view can be found in the &lt;a href="https://slack.com/help/articles/226410907-View-all-your-unread-messages" rel="noopener noreferrer"&gt;Slack help article&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final word&lt;a href="https://www.progractivity.com/flow/coding-in-quiet-how-i-solved-slack-noise-as-a-developer/#final-word" rel="noopener noreferrer"&gt;​&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This shift in perspective towards our digital tools has been a game-changer. Recognizing the asynchronous nature of chat apps allows me to manage my focus and productivity better. Other steps like app usage routine, changing settings or notifications are grounded on this idea.&lt;/p&gt;

&lt;p&gt;It’s about setting boundaries and remembering that in the realm of software development, &lt;strong&gt;uninterrupted time is not a luxury—it’s a necessity&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>learning</category>
      <category>agile</category>
    </item>
    <item>
      <title>How to configure import alias in React Native</title>
      <dc:creator>Daniel Koprowski</dc:creator>
      <pubDate>Tue, 25 May 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/koprowski_it/how-to-configure-import-alias-in-react-native-579k</link>
      <guid>https://dev.to/koprowski_it/how-to-configure-import-alias-in-react-native-579k</guid>
      <description>&lt;p&gt;Import aliases are better for maintenance and more readable. Learn how to set up them in React Native!&lt;/p&gt;

&lt;p&gt;Look at those two examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&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;InputArea&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;~components/InputArea&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="mi"&gt;2&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;InputArea&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;../../../../../components/InputArea&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will learn how to set up our environment to have the first variant working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aliases for &lt;code&gt;src&lt;/code&gt; folder
&lt;/h2&gt;

&lt;p&gt;For this tutorial, I assume that we have a standard React Native file structure. We want to create aliases to directories inside the &lt;code&gt;src&lt;/code&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── App.js
├── __tests__
├── android
├── app.json
├── babel.config.js
├── index.js
├── ios
├── metro.config.js
├── node_modules
├── package.json
├── src
│   ├── components
│   └── helpers
└── yarn.lock

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why is the tilde prefix &lt;code&gt;~&lt;/code&gt; important?
&lt;/h2&gt;

&lt;p&gt;The custom prefix is helpful when it comes to distinguishing your local imports from third-party packages. One look and you know which imports are from the project.&lt;/p&gt;

&lt;p&gt;Here are two examples with the &lt;code&gt;helpers&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&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;something&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;helpers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// - without prefix&lt;/span&gt;
&lt;span class="mi"&gt;2&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;something&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;~helpers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// - with prefix&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a package in the npm registry that is called &lt;code&gt;helpers&lt;/code&gt;. If you decide to alias your &lt;code&gt;helpers&lt;/code&gt; folder without any prefix then you risk a naming conflict.&lt;/p&gt;

&lt;p&gt;I decided to stick with &lt;code&gt;~&lt;/code&gt; as I haven't seen third party packages that use it. &lt;em&gt;There are other popular prefixes as well — my recommendation is sticking with tilde&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Babel plugin
&lt;/h2&gt;

&lt;p&gt;First of all, we have to add a proper plugin for the Babel compiler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;▶ yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; babel-plugin-module-resolver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adjust Babel config
&lt;/h2&gt;

&lt;p&gt;Inside &lt;code&gt;babel.config.js&lt;/code&gt; add &lt;code&gt;plugins&lt;/code&gt; section. If it already exists, simply add &lt;code&gt;module-resolver&lt;/code&gt; config like below. If you don't have this file. Then check for &lt;code&gt;.babelrc&lt;/code&gt; or create one. All possible config files are listed &lt;a href="https://babeljs.io/docs/en/config-files" rel="noopener noreferrer"&gt;in the docs&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    // ... some other config
  plugins: [
    // ... some other plugins
    [
      'module-resolver',
      {
        root: ['./'],
        alias: {
          /**
           * Regular expression is used to match all files inside `./src` directory and map each `.src/folder/[..]` to `~folder/[..]` path
           */
          '^~(.+)': './src/\\1',
        },
        extensions: [
          '.ios.js',
          '.android.js',
          '.js',
          '.jsx',
          '.json',
          '.tsx',
          '.ts',
          '.native.js',
        ],
      },
    ],
  ],
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Options are as described:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;root - a string or an array of root directories,&lt;/li&gt;
&lt;li&gt;alias - a map of aliases,&lt;/li&gt;
&lt;li&gt;extensions - an array of file extensions used in the resolver.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Regular expression as an alias
&lt;/h3&gt;

&lt;p&gt;To prevent adding each &lt;code&gt;src&lt;/code&gt; subfolder separately we want to use a regular expression for path completion. You can see the docs about using regular expressions on &lt;a href="https://github.com/tleunen/babel-plugin-module-resolver/blob/master/DOCS.md#regular-expressions" rel="noopener noreferrer"&gt;babel-plugin-module-resolver Github page&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Restart metro process
&lt;/h3&gt;

&lt;p&gt;The last step to make it work is restarting the &lt;em&gt;metro&lt;/em&gt; server. Simply use &lt;code&gt;ctrl + c&lt;/code&gt; and then &lt;code&gt;yarn start&lt;/code&gt; again in the terminal in your project.&lt;/p&gt;

&lt;p&gt;If something is not working maybe you have to clear the cache - for that use &lt;code&gt;yarn start --reset-cache&lt;/code&gt; command.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to make VSCode alias autocomplete working?
&lt;/h2&gt;

&lt;p&gt;With the config above code will compile and work as expected. Now we would like to have autocomplete work with our newly created aliases (or &lt;em&gt;IntelliSense&lt;/em&gt; as named by Visual Studio Code creators).&lt;/p&gt;

&lt;p&gt;We have to enter &lt;code&gt;jsconfig.json&lt;/code&gt; file (or create it if it's not working).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~*": ["src/*"]
    }
  },
  "exclude": ["node_modules"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;code&gt;jsconfig.json&lt;/code&gt; we have to specify two options: &lt;code&gt;baseUrl&lt;/code&gt; and &lt;code&gt;paths&lt;/code&gt; object. Here again, we are using a kind of regular expression to match all subdirectories in a single line.&lt;/p&gt;

&lt;h3&gt;
  
  
  TypeScript support
&lt;/h3&gt;

&lt;p&gt;What is interesting - in the TypeScript project I had to make a config a bit different to make it work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {"~*": ["./src/*"]}, 
  },
  "exclude": ["node_modules"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the dot before &lt;code&gt;src&lt;/code&gt; path. I don't know why it required such a change. Maybe you have some idea? Let me know!&lt;/p&gt;

&lt;p&gt;You can also check config in the &lt;a href="https://reactnative.dev/docs/typescript#using-custom-path-aliases-with-typescript" rel="noopener noreferrer"&gt;official docs for TypeScript aliases&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Restart TypeScript process in VSCode
&lt;/h3&gt;

&lt;p&gt;Autocomplete with new aliases should work immediately. If it is not maybe you have to restart TypeScript server (even for pure JS project as this server is responsible for autocompletion).&lt;/p&gt;

&lt;p&gt;To do this open the command palette and type &lt;code&gt;Restart TS server&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Thanks for reading
&lt;/h4&gt;

&lt;p&gt;👉 &lt;a href="//twitter.com/Koprowski_it"&gt;Check out latest React Native tips on my Twitter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://koprowski.it/subscribe" rel="noopener noreferrer"&gt;Stay updated about new tutorials on my Newsletter ✉️&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>tutorial</category>
      <category>react</category>
    </item>
    <item>
      <title>Handy form validation in React Native with react-hook-form useController</title>
      <dc:creator>Daniel Koprowski</dc:creator>
      <pubDate>Tue, 02 Feb 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/koprowski_it/handy-form-validation-in-react-native-with-react-hook-form-usecontroller-238o</link>
      <guid>https://dev.to/koprowski_it/handy-form-validation-in-react-native-with-react-hook-form-usecontroller-238o</guid>
      <description>&lt;p&gt;Managing forms in React Native is different than in web React. We don’t have shortcuts and HTML to register field through ref. I wanted to create a handy solution that satisfies those requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;easy to understand,&lt;/li&gt;
&lt;li&gt;scalable,&lt;/li&gt;
&lt;li&gt;reusable,&lt;/li&gt;
&lt;li&gt;minor boilerplate,&lt;/li&gt;
&lt;li&gt;hook centric.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After days of experiments, I managed to create a solution that made me satisfied and this article is a summary of my work. I believe this will be helpful to you.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use react-hook-form with React Native
&lt;/h3&gt;

&lt;p&gt;I decided to use &lt;code&gt;react-hook-form&lt;/code&gt; as it gains more and more popularity and there are good reasons for that.&lt;/p&gt;

&lt;p&gt;This article may be considered a forms tutorial in React Native.&lt;/p&gt;

&lt;p&gt;The methodology presented in the article could be also used with &lt;code&gt;formik&lt;/code&gt; or other similar packages of your choice. First read through the end and check if your form management package has similar API.&lt;/p&gt;

&lt;p&gt;Imports, exports and other miscellaneous code like PropTypes will not be included in code snippets to avoid overload. Examples are a simplified version of original files that can be found &lt;a href="https://github.com/dkoprowski/react-native-form-validation-tutorial" rel="noopener noreferrer"&gt;on git repository&lt;/a&gt; attached to this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  0. Prepare project
&lt;/h2&gt;

&lt;p&gt;I’ve created new React Native project and prepared it for our example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx react-native init ElegantFormManagement

cd ElegantFormManagement

yarn &amp;amp;&amp;amp; yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1. Create login form UI without any logic
&lt;/h2&gt;

&lt;p&gt;Let’s start with an easy task. We will create the wireframe of our form first. Add &lt;code&gt;src/components&lt;/code&gt; directory inside the root of the project.&lt;/p&gt;

&lt;p&gt;Now we need two new files &lt;code&gt;Input.js&lt;/code&gt; and &lt;code&gt;Login.js&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Input.js
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Input.js&lt;/code&gt; is a wrapper for React Native’s &lt;code&gt;TextInput&lt;/code&gt; component. It has extended functionality to show label above the input field and &lt;em&gt;(if provided)&lt;/em&gt; validation error beneath it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Label&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;label&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;Label&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;TextInput&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isError&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Error&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;error&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;Error&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  A word about styling components
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;styled-components&lt;/code&gt; will be used in the examples to make components more readable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add styled-components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks to &lt;code&gt;'styled-components/native'&lt;/code&gt; &lt;em&gt;(notice &lt;code&gt;/native&lt;/code&gt; suffix)&lt;/em&gt; we can use React Native’s components instead of HTML elements. For example &lt;code&gt;styled.View&lt;/code&gt; instead of &lt;code&gt;styled.div&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you are not familiar with this method of styling this is a quick comparison:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Label&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;COLORS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
  font-size: 10px;
  letter-spacing: 2px;
`&lt;/span&gt;

&lt;span class="c1"&gt;// will look the same as:&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;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
    &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;COLORS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;letterSpacing&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="p"&gt;}}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Input.js code
&lt;/h4&gt;

&lt;p&gt;In the code below you can see that conditional rendering &lt;code&gt;{Boolean(value) &amp;amp;&amp;amp; &amp;lt;Something /&amp;gt;}&lt;/code&gt; is secured by &lt;code&gt;Boolean()&lt;/code&gt; function. If you are curious or don’t understand why I did that read how &lt;a href="https://koprowski.it/2020/conditional-rendering-react-native-text-crash/" rel="noopener noreferrer"&gt;conditional rendering in React Native may crash your app&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/Input.js&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="s1"&gt;styled-components/native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Wrapper&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;View&lt;/span&gt;&lt;span class="s2"&gt;`
  margin-bottom: 15px;
`&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StyledInput&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;TextInput&lt;/span&gt;&lt;span class="s2"&gt;`
  border-color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isError&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;COLORS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;red&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;COLORS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;;
  border-width: 1;
`&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Label&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;COLORS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
  font-size: 10px;
  letter-spacing: 2px;
`&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;Error&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;COLORS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;red&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;Input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;label&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="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;isError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Boolean&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="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;Wrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Label&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;label&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;Label&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;lt;&lt;/span&gt;&lt;span class="nc"&gt;StyledInput&lt;/span&gt; &lt;span class="na"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="si"&gt;}&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;isError&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Error&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;error&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;Error&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;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Wrapper&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;h3&gt;
  
  
  Login.js
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Login.js&lt;/code&gt; will be our form. For now, it is just mocked component. It consists of two input fields for username &amp;amp; password and a submit button.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/Login.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Login&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;View&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;Input&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Username'&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;Input&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Password'&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Password can't be blank"&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;Button&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Login'&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  App.js
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;App.js&lt;/code&gt; is React Native’s standard input starting scene. Remove everything from it and just render &lt;code&gt;&amp;lt;Login /&amp;gt;&lt;/code&gt; form inside.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.js&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="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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Login&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now our app looks like this:&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%2Foc6rnq9q935akmx9w778.jpg" 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%2Foc6rnq9q935akmx9w778.jpg" alt="Login form" width="800" height="1375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To check full source code on this step visit branch &lt;a href="https://github.com/dkoprowski/react-native-form-validation-tutorial/tree/01-create-basic-ui" rel="noopener noreferrer"&gt;&lt;code&gt;01-create-basic-ui&lt;/code&gt; on git repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create a form
&lt;/h2&gt;

&lt;p&gt;The time has come to install &lt;code&gt;react-hook-form&lt;/code&gt; package.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install react-hook-form
&lt;/h3&gt;

&lt;p&gt;Stop your metro bundler and install the package using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add react-hook-form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are ready to introduce some logic into our UI &lt;code&gt;&amp;lt;Login /&amp;gt;&lt;/code&gt; mock.&lt;/p&gt;

&lt;h3&gt;
  
  
  Import form’s brain
&lt;/h3&gt;

&lt;p&gt;Our form will live inside an object returned by &lt;code&gt;useForm()&lt;/code&gt; hook. Let’s call this object &lt;code&gt;formMethods&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now import needed hook and add &lt;code&gt;const formMethods = useForm()&lt;/code&gt; inside &lt;code&gt;&amp;lt;Login /&amp;gt;&lt;/code&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/Login.js&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;useForm&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-hook-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Login&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;formMethods&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useForm&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;Wrapper&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;Input&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Username'&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;Input&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Password'&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Password can't be blank"&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;Button&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Login'&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;Wrapper&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;Next, we will have to communicate with form fields. To achieve this we will pass &lt;code&gt;formMethods&lt;/code&gt; to our Input components.&lt;/p&gt;

&lt;p&gt;Full source code: &lt;a href="https://github.com/dkoprowski/react-native-form-validation-tutorial/tree/02-create-form" rel="noopener noreferrer"&gt;02-create-form on git repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Establish communication with form fields
&lt;/h2&gt;

&lt;p&gt;The biggest challenge in an elegant way of making things is to avoid too much “magic”. Code needs to be easy to read but also understandable for other programmers. We write code for ourselves and our colleagues and not for the computer. If we would write code for the computer then we should use Assembly or even lower-level language.&lt;/p&gt;

&lt;p&gt;React Context is just a little magic touch. It will simplify code and when used with care will not add much complexity to our solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is React Context?
&lt;/h3&gt;

&lt;p&gt;Long story short instead of passing lots of component props we will provide the same information with so-called “context” to component’s children. Then each child has access to the context through a hook 🎣.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add FormProvider to pass form context
&lt;/h3&gt;

&lt;p&gt;I mentioned that our form lives inside &lt;code&gt;formMethods&lt;/code&gt;. We have to pass the contents of this object to form fields. In this case, our fields are &lt;code&gt;&amp;lt;Input /&amp;gt;&lt;/code&gt; components for username and password.&lt;/p&gt;

&lt;p&gt;We put everything that is inside &lt;code&gt;formMethods&lt;/code&gt; into context. To do this we have to import &lt;code&gt;&amp;lt;FormProvider /&amp;gt;&lt;/code&gt; from &lt;code&gt;react-hook-form&lt;/code&gt;. Now we pass everything from &lt;code&gt;formMethods&lt;/code&gt; to &lt;code&gt;FormProvider&lt;/code&gt; using object spread operator &lt;code&gt;{...formMethods}&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/Login.js&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;FormProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useForm&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-hook-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Login&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;formMethods&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useForm&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;Wrapper&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;FormProvider&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;formMethods&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;Input&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Username'&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;Input&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Password'&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Password can't be blank"&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;FormProvider&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;Button&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Login'&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;Wrapper&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;Note that I’m not wrapping &lt;code&gt;Button&lt;/code&gt; as a child of the &lt;code&gt;FormProvider&lt;/code&gt;. It is a crucial element of our form as pressing it will submit the whole thing. We will interact with a button using good old props so it doesn’t have to know everything that happens inside the form.&lt;/p&gt;

&lt;p&gt;See branch &lt;a href="https://github.com/dkoprowski/react-native-form-validation-tutorial/tree/03-pass-context-to-fields" rel="noopener noreferrer"&gt;03-pass-context-to-fields&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Add logic to the Input component
&lt;/h2&gt;

&lt;p&gt;Our UI skeleton of &lt;code&gt;&amp;lt;Input /&amp;gt;&lt;/code&gt; is not doing anything yet except showing label and error. It doesn’t provide props to manipulate &lt;code&gt;&amp;lt;TextInput /&amp;gt;&lt;/code&gt; which is inside of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pass props to Input
&lt;/h3&gt;

&lt;p&gt;We will use spread operator again to assign all &lt;code&gt;Input&lt;/code&gt; props (except &lt;code&gt;label&lt;/code&gt; and &lt;code&gt;error&lt;/code&gt;) to object named &lt;code&gt;textInputProps&lt;/code&gt;. Next, we have to pass this object to &lt;code&gt;StyledInput&lt;/code&gt; which is just a styled version of standard React Native &lt;code&gt;TextInput&lt;/code&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/Input.js&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;Input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;label&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;textInputProps&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;isError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Boolean&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="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;Wrapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Label&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;label&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;Label&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;lt;&lt;/span&gt;&lt;span class="nc"&gt;StyledInput&lt;/span&gt; &lt;span class="na"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;textInputProps&lt;/span&gt;&lt;span class="si"&gt;}&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;isError&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Error&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;error&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;Error&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;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Wrapper&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;h3&gt;
  
  
  Create FormInput wrapper
&lt;/h3&gt;

&lt;p&gt;We have a very simple &lt;code&gt;Input&lt;/code&gt; component which is easy to test and expand in the future. Keep it this way.&lt;/p&gt;

&lt;p&gt;We want to add logic into this component. Instead of adding the logic directly inside &lt;code&gt;Input&lt;/code&gt; and tie it with our form management solution, we will create a new component. It will use &lt;code&gt;Input&lt;/code&gt; internally and equips it with extra features.&lt;/p&gt;

&lt;h3&gt;
  
  
  FormInput takes control over Input
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;FormInput&lt;/code&gt; takes a bit different props than &lt;code&gt;Input&lt;/code&gt;. For example, it will decide internally about &lt;code&gt;error&lt;/code&gt;, and &lt;code&gt;value&lt;/code&gt; props of &lt;code&gt;Input&lt;/code&gt; so we cannot pass such props to it.&lt;/p&gt;

&lt;p&gt;We establish a connection with form headquarters. To achieve this we add &lt;code&gt;useFormContext()&lt;/code&gt; hook which returns the object that we’ve passed through &lt;code&gt;&amp;lt;FormProvider /&amp;gt;&lt;/code&gt;. As an example, we can read all form errors accessing &lt;code&gt;formContext.errors&lt;/code&gt; field.&lt;/p&gt;

&lt;p&gt;Take a look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/FormInput.js&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;useFormContext&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-hook-form&lt;/span&gt;&lt;span class="dl"&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;FormInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultValue&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;inputProps&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormContext&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;errors&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formContext&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;Input&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;inputProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&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;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  The &lt;code&gt;name&lt;/code&gt; prop
&lt;/h4&gt;

&lt;p&gt;It is required for every field in the form to have a unique name. Therefore we pass &lt;code&gt;name&lt;/code&gt; prop to every form field. &lt;strong&gt;It is an identifier of a field.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Errors object
&lt;/h4&gt;

&lt;p&gt;To show proper error on &lt;code&gt;Input&lt;/code&gt; component access &lt;code&gt;errors&lt;/code&gt; object from context. Then check whether there is an error message for our field &lt;code&gt;errors[name].&lt;/code&gt; If there are no errors then &lt;code&gt;errors[name]&lt;/code&gt; is undefined - therefore we have to be careful. To access error message I use quite a new &lt;strong&gt;optional chaining&lt;/strong&gt; operator ( &lt;strong&gt;&lt;code&gt;?.&lt;/code&gt;&lt;/strong&gt; ).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;?.&lt;/code&gt; operator functions similarly to the &lt;code&gt;.&lt;/code&gt; chaining operator, except that instead of causing an error if a reference is &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Nullish" rel="noopener noreferrer"&gt;nullish&lt;/a&gt; (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null" rel="noopener noreferrer"&gt;&lt;code&gt;null&lt;/code&gt;&lt;/a&gt; or &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined" rel="noopener noreferrer"&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/a&gt;), the expression short-circuits with a return value of &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If there is an error message then &lt;code&gt;Input&lt;/code&gt; will receive it. Otherwise, it will receive &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  useController
&lt;/h4&gt;

&lt;p&gt;We have a connection with form so let’s use it! Well,… almost.&lt;/p&gt;

&lt;p&gt;We will now use our form to store this &lt;code&gt;FormInput&lt;/code&gt;’s value. First, we have to create our field instance with &lt;code&gt;useController&lt;/code&gt; hook. Take a look at the code example below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/FormInput.js&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;useController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useFormContext&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-hook-form&lt;/span&gt;&lt;span class="dl"&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;FormInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultValue&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;inputProps&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormContext&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;control&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formContext&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;field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useController&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultValue&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;Input&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;inputProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&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;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;useController&lt;/code&gt; the most important config fields are &lt;code&gt;name&lt;/code&gt; as mentioned before and &lt;code&gt;control&lt;/code&gt; object. The connection between the field and form is established by providing the &lt;code&gt;control&lt;/code&gt; object to the controller.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep in mind that &lt;code&gt;control&lt;/code&gt; is a central point of the form&lt;/strong&gt;, this is “the form’s brain” I was mentioning before.&lt;/p&gt;

&lt;p&gt;To add some restrictions for the field (e.g. &lt;code&gt;maxLength&lt;/code&gt;, &lt;code&gt;required&lt;/code&gt;) there is &lt;code&gt;rules&lt;/code&gt; object. We can also use &lt;code&gt;yup&lt;/code&gt; schema or custom resolver function.&lt;/p&gt;

&lt;h4&gt;
  
  
  field
&lt;/h4&gt;

&lt;p&gt;To keep the value and status of &lt;code&gt;Input&lt;/code&gt; we have a &lt;code&gt;field&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;From now on &lt;code&gt;Input&lt;/code&gt; is controlled by &lt;code&gt;field&lt;/code&gt; object so we pass &lt;code&gt;value&lt;/code&gt; and event handlers &lt;em&gt;(&lt;code&gt;onBlur&lt;/code&gt; and &lt;code&gt;onChange&lt;/code&gt;)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;All properties of the field: &lt;code&gt;{ onChange, onBlur, value, name, ref }&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/FormInput.js&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;useController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useFormContext&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-hook-form&lt;/span&gt;&lt;span class="dl"&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;FormInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultValue&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;inputProps&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormContext&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;control&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formContext&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;field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useController&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultValue&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;Input&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;inputProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onChangeText&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onBlur&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onBlur&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that on &lt;code&gt;Input&lt;/code&gt; component we use &lt;code&gt;onChangeText&lt;/code&gt; prop to get &lt;code&gt;string&lt;/code&gt; instead of &lt;code&gt;event&lt;/code&gt; from input field: &lt;code&gt;onChangeText={field.onChange}&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Login
&lt;/h3&gt;

&lt;p&gt;Change &lt;code&gt;Input&lt;/code&gt; components to &lt;code&gt;FormInput&lt;/code&gt; inside our main form view: &lt;code&gt;Login.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I’ve also removed &lt;code&gt;error&lt;/code&gt; prop from password Input as this is no longer demo view — it almost works!&lt;/p&gt;

&lt;h4&gt;
  
  
  LOGIN_FIELDS
&lt;/h4&gt;

&lt;p&gt;Forms can grow with time so it is wise to keep all constants in variables. I’ve created &lt;code&gt;LOGIN_FIELDS&lt;/code&gt; const for field names. It prevents from making typos and searching for a minor bug for hours in the future.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/Login.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LOGIN_FIELDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&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;Login&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;formMethods&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useForm&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;Wrapper&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;FormProvider&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;formMethods&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;FormInput&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;LOGIN_FIELDS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Username'&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;FormInput&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;LOGIN_FIELDS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Password'&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;FormProvider&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;Button&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Login'&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;Wrapper&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;Right now our form stores values and react to changes. Fields are connected with central &lt;code&gt;formMethods&lt;/code&gt; object but we lack any validation and submitting. Let’s dive into it in the next section.&lt;/p&gt;

&lt;p&gt;To see full source check branch &lt;a href="https://github.com/dkoprowski/react-native-form-validation-tutorial/tree/04-create-form-input" rel="noopener noreferrer"&gt;04-create-form-input&lt;/a&gt; on a git repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Validate &amp;amp; submit
&lt;/h2&gt;

&lt;p&gt;To send data from a form we have to take care of the login button.&lt;/p&gt;

&lt;p&gt;Create two handlers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;onSubmit&lt;/code&gt; which takes a whole form as an argument when it is valid,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onErrors&lt;/code&gt; which will handle errors in the form.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we pass &lt;code&gt;handleSubmit&lt;/code&gt; function from &lt;code&gt;formMethods&lt;/code&gt; to &lt;code&gt;onPress&lt;/code&gt; prop of our button. &lt;code&gt;handleSubmit&lt;/code&gt; function takes two callbacks as arguments — &lt;code&gt;onSubmit&lt;/code&gt; and &lt;code&gt;onError&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/Login.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Login&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;formMethods&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useForm&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;onSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;form&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;onErrors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;errors&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errors&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Wrapper&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;FormProvider&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;formMethods&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;FormInput&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;LOGIN_FIELDS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Username'&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;FormInput&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;LOGIN_FIELDS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Password'&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;FormProvider&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;Button&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Login'&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="nx"&gt;formMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onErrors&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;Wrapper&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;h3&gt;
  
  
  No rules
&lt;/h3&gt;

&lt;p&gt;There are no rules so the form is always valid! At this point every button press will call &lt;code&gt;onSubmit&lt;/code&gt;. &lt;code&gt;onErrors&lt;/code&gt; is ignored. We have to add some restrictions for username and password.&lt;/p&gt;

&lt;p&gt;Pass &lt;code&gt;rules&lt;/code&gt; object as prop to &lt;code&gt;FormInput&lt;/code&gt;. Notice that more complex rules as &lt;code&gt;minLength&lt;/code&gt; are represented by an object and simple rule like &lt;code&gt;required&lt;/code&gt; can be just represented by a string with an error message. To understand how rules works see &lt;code&gt;react-hook-form&lt;/code&gt; docs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;At this point we could use &lt;code&gt;yup&lt;/code&gt; schema instead of rules. Schemas are much more powerful in terms of form validation. I will not cover this here to not overcomplicate this article. If you’re interested let me know in the comments! I can prepare “part 2” of adventures of the forms.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/Login.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Login&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;formMethods&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useForm&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;onSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;form&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;onErrors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;errors&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errors&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Wrapper&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;FormProvider&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;formMethods&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;FormInput&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;LOGIN_FIELDS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Username'&lt;/span&gt;
          &lt;span class="na"&gt;rules&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;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Username is required!&lt;/span&gt;&lt;span class="dl"&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;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FormInput&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;LOGIN_FIELDS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Password'&lt;/span&gt;
          &lt;span class="na"&gt;rules&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;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password is required!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;minLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Use at least 10 characters.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&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="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;FormProvider&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;Button&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Login'&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="nx"&gt;formMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onErrors&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;Wrapper&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;We have handled a very basic scenario of the login form. Now let’s take a look at what we can improve in this simple solution.&lt;/p&gt;

&lt;p&gt;To check full source code at this point check &lt;a href="https://github.com/dkoprowski/react-native-form-validation-tutorial/tree/05-submit-form" rel="noopener noreferrer"&gt;05-submit-form&lt;/a&gt; branch on git repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Make every form field error-proof
&lt;/h2&gt;

&lt;p&gt;We mentioned before that form field requires &lt;code&gt;name&lt;/code&gt; and form context. To achieve this we pass &lt;code&gt;name&lt;/code&gt; through prop and we take context from &lt;code&gt;useFormContext&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;The assumption that the author of the code and every developer in the team will always pass proper prop and wrap our form in &lt;code&gt;FormProvider&lt;/code&gt; is too optimistic. We have to make code error-proof.&lt;/p&gt;

&lt;p&gt;It would be nice to give a proper message for the developer that something is forgotten. Unless we’d like to show our users one of those errors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;TypeError: Cannot read property 'split' of undefined&lt;/code&gt; happens when you forget to pass name prop,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TypeError: Cannot read property 'control' of null&lt;/code&gt; pops up when a field is not wrapped in &lt;code&gt;FormProvider&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We could simply try to apply conditional rendering here like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//  ... Don't do this:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormContext&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;formContext&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;name&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="kc"&gt;null&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;field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useController&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultValue&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it would break React rule to not call hooks conditionally and if you have properly configured ESLint you’d see such error:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;React Hook "useController" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Another wrapper
&lt;/h3&gt;

&lt;p&gt;This might not seem so pretty at first glance but it makes things done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it keeps hooks call order always the same,&lt;/li&gt;
&lt;li&gt;makes the wrapped component safe.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the code snippet below I renamed old &lt;code&gt;FormInput&lt;/code&gt; component to &lt;code&gt;ControlledInput&lt;/code&gt; and removed &lt;code&gt;export&lt;/code&gt; from it to make it “private”. This prevents importing of &lt;code&gt;ControlledInput&lt;/code&gt; in other files in the project.&lt;/p&gt;

&lt;p&gt;Next, I’ve created a new “public” component - the wrapper. Now this one is called &lt;code&gt;FormInput&lt;/code&gt; and is exported from the file. Logic inside the wrapper is straight forward. It checks whether &lt;code&gt;formContext&lt;/code&gt; or &lt;code&gt;name&lt;/code&gt; is falsy and if this is the case wrapper returns &lt;code&gt;&amp;lt;Input /&amp;gt;&lt;/code&gt; with a proper error message. &lt;strong&gt;I also block editing on those fields to make sure that integration tests fail.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Adding error messages makes it easier to debug when something goes wrong in the future. Thanks to this your automatic tests or QA team will detect instantly that something is wrong.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/FormInput.js&lt;/span&gt;

&lt;span class="c1"&gt;// "private" component - created from old "FormInput"&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ControlledInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultValue&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;inputProps&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormContext&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;control&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formContext&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;field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useController&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defaultValue&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;Input&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;inputProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onChangeText&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onBlur&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onBlur&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// wrapper - our new FormInput&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;FormInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;inputProps&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFormContext&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;formContext&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;name&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;errorMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Form field must have a "name" prop!&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="s1"&gt;Form field must be a descendant of `FormProvider` as it uses `useFormContext`!&lt;/span&gt;&lt;span class="dl"&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;Input&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;inputProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;editable&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&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;}&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;ControlledInput&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&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;To see full source of &lt;code&gt;FormInput.js&lt;/code&gt; at this point check branch &lt;a href="https://github.com/dkoprowski/react-native-form-validation-tutorial/tree/06-error-proof-fields" rel="noopener noreferrer"&gt;06-error-proof-fields&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next?
&lt;/h2&gt;

&lt;p&gt;With &lt;code&gt;FormInput.js&lt;/code&gt; base you can similarly build other form fields like: &lt;code&gt;FormChecbox&lt;/code&gt;, &lt;code&gt;FormTextArea&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;We could add more content here like: use yup schemas, describe how to focus password field from the keyboard, how to pass &lt;code&gt;ref&lt;/code&gt; to &lt;code&gt;FormInput&lt;/code&gt;, create a custom hook for shared form field logic, how to test form… My first draft for this article contained all those things but it started to be overloaded! I can use it next time if you’d like to read it. Let me know!&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Ready Forms
&lt;/h2&gt;

&lt;p&gt;While working on this article I decided that I’ll create production-ready forms for React Native! The library of components and &lt;strong&gt;whole views&lt;/strong&gt; that you could reuse in your app.&lt;/p&gt;

&lt;p&gt;For example ready-to-use registration form, login form, app opinion form, chat etc. Everything that could speedup work of React Native developer or a team. I will also prepare a ready App with all those forms - you will be able to download it and adjust for your needs.&lt;/p&gt;

&lt;p&gt;I get so excited that I acquired a domain: &lt;a href="https://productionreadyforms.com/" rel="noopener noreferrer"&gt;productionReadyForms.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I will notify you when this package is ready! You can leave me your email in the newsletter form on &lt;a href="https://productionreadyforms.com/" rel="noopener noreferrer"&gt;the website&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Twitter
&lt;/h2&gt;

&lt;p&gt;Check out my Twitter account. I write mostly about React Native, JavaScript and Productivity.&lt;/p&gt;

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

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



&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Conditional rendering in React Native may crash your app</title>
      <dc:creator>Daniel Koprowski</dc:creator>
      <pubDate>Sun, 26 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/koprowski_it/conditional-rendering-in-react-native-may-crash-your-app-1k16</link>
      <guid>https://dev.to/koprowski_it/conditional-rendering-in-react-native-may-crash-your-app-1k16</guid>
      <description>&lt;p&gt;Very soon after start of creating first app every developer needs to render component in one way or another depending on props. When one start searching, the first answer is inside React documentation. The answer is “Conditional Rendering”. But after a while many of us starts facing errors in React Native (or wrong rendering in React for web) that seems to jump on occasionally to reappear some time later. This article will explain what is happening and how to prevent further mistakes.&lt;/p&gt;

&lt;p&gt;Conditional rendering using inline If with logical &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; (AND) operator as React docs says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You may embed &lt;em&gt;any expressions&lt;/em&gt; in JSX by wrapping them in curly braces. This includes the JavaScript logical &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator. It can be handy for conditionally including an element — &lt;a href="https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator" rel="noopener noreferrer"&gt;React docs: Conditional Rendering&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;someValue&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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="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;field&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;Text&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;someValue&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;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;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This handy solution is used by many and it’s nothing new for our community to see in the code. How and why it can crash your React Native app?&lt;/p&gt;

&lt;p&gt;When using it widely in your App without proper attention sooner or later you will see this error (or &lt;em&gt;worse scenario&lt;/em&gt; your users will see that the app crashed):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Invariant Violation: Text strings must be rendered within a &amp;lt;Text&amp;gt; component.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then you see such an error in your logs and scratch your head because usually it works, it may crash for one particular data entry or after some small API change. What happened? &lt;em&gt;Hint: &lt;code&gt;someValue&lt;/code&gt; type matters.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  The array example
&lt;/h4&gt;

&lt;p&gt;Another common example of javascript operator wrong usage is rendering something is array contains any elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Sooner or later this code will surprise users.&lt;/span&gt;
&lt;span class="c1"&gt;// Just wait for an empty array.&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dataEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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="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;Visible only when array is not empty&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;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above example looks fine at a first glance. Array’s &lt;code&gt;length&lt;/code&gt; will be &lt;code&gt;0&lt;/code&gt; which is &lt;em&gt;falsy&lt;/em&gt; thus condition is not satisfied and following component is not rendered — simple. This reasoning is &lt;em&gt;partially good&lt;/em&gt; but author may forgot about one little fact that will surprise users at some point. Let’s take a closer look.&lt;/p&gt;

&lt;h2&gt;
  
  
  How logical AND &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator in JavaScript works?
&lt;/h2&gt;

&lt;p&gt;Let’s see the docs again:&lt;/p&gt;

&lt;blockquote&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operator&lt;/th&gt;
&lt;th&gt;Syntax&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Logical AND (&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;expr1 &amp;amp;&amp;amp; expr2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If &lt;code&gt;expr1&lt;/code&gt; can be converted to &lt;code&gt;true&lt;/code&gt;, returns &lt;code&gt;expr2&lt;/code&gt;; else, returns &lt;code&gt;expr1&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;[…]If a value can be converted to &lt;code&gt;true&lt;/code&gt;, the value is so-called &lt;em&gt;truthy&lt;/em&gt;. If a value can be converted to &lt;code&gt;false&lt;/code&gt;, the value is so-called &lt;em&gt;falsy&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Examples of expressions that can be converted to false are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;null&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NaN&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;empty string (&lt;code&gt;''&lt;/code&gt; [..]);&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;undefined&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators" rel="noopener noreferrer"&gt;MDN docs: Logical operators&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Developers love that possibility to treat variables as &lt;em&gt;falsy&lt;/em&gt;. Assumption is that when your variable for some reason comes not initialised from backend or other data source you have secured the code from rendering this part of View.&lt;/p&gt;

&lt;p&gt;It seems to be a good strategy. We don’t want to show our user nicely formatted &lt;code&gt;undefined&lt;/code&gt; string. It’s better to show nothing than &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;NaN&lt;/code&gt; as well.&lt;/p&gt;

&lt;p&gt;Note that description of AND operator says that it returns &lt;code&gt;expr1&lt;/code&gt; or &lt;code&gt;expr2&lt;/code&gt;. It always returns one of inputs — not converted. Again: &lt;strong&gt;it converts &lt;code&gt;expr1&lt;/code&gt; to &lt;code&gt;Boolean&lt;/code&gt; and evaluates result but then returns original value not the converted one.&lt;/strong&gt; Explained as pseudo code it should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expr1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&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="nx"&gt;expr2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;expr1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically it is the whole gotcha but let’s dive into examples. I will use &lt;code&gt;Boolean()&lt;/code&gt; JavaScript function to show you how values are converted.&lt;/p&gt;

&lt;h3&gt;
  
  
  String variable.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;

&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;

&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;// space&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;

&lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;conditionally returned string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; ''&lt;/span&gt;

&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;conditionally returned string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; 'conditionally returned string'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Empty string is &lt;em&gt;falsy&lt;/em&gt; so AND operator will return &lt;code&gt;''&lt;/code&gt; because the condition is not fulfilled. Returning &lt;code&gt;''&lt;/code&gt; directly into ReactNative JSX will produce error &lt;code&gt;Text strings must be rendered within a &amp;lt;Text&amp;gt; component&lt;/code&gt; and &lt;strong&gt;cause crash&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Numeric variable.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;

&lt;span class="nc"&gt;Boolean&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="c1"&gt;// -&amp;gt; false&lt;/span&gt;

&lt;span class="nc"&gt;Boolean&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="c1"&gt;// -&amp;gt; true&lt;/span&gt;

&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;conditionally returned string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; 0&lt;/span&gt;

&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;conditionally returned string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; 'conditionally returned string'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero is &lt;em&gt;falsy&lt;/em&gt; so logical AND operator will return &lt;code&gt;0&lt;/code&gt; as the condition is not met. Returning &lt;code&gt;0&lt;/code&gt; into ReactNative JSX will cause crash with &lt;code&gt;Invariant Violation&lt;/code&gt; error again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other variable types worth mentioning.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;

&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;

&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;

&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt; &lt;span class="c1"&gt;// worth noting!&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the above examples the most interesting from React Native developer’s point of view is array. Usually when we put array into conditional render we would like not to render anything if array is empty. Passing an empty array into logical expression without any preparation will mislead us. What one would need to do is to check whether &lt;code&gt;length&lt;/code&gt; exists and is equal to &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why React Native crashes?
&lt;/h2&gt;

&lt;p&gt;Rendering string in React Native must be wrapped with &lt;code&gt;&amp;lt;Text&amp;gt;...&amp;lt;/Text&amp;gt;&lt;/code&gt; component. But when we want to hide entire component when variable is empty with conditional rendering it may return an empty string directly into JSX. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;optionalStr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;

&lt;span class="c1"&gt;// [...] some logic that leaves `optionalStr` empty&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;optionalStr&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;optionalStr&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;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;}&lt;/span&gt; &lt;span class="c1"&gt;// crash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you know that above condition is not fulfilled therefore logical AND operator will return &lt;code&gt;optionalStr&lt;/code&gt; directly into main JSX.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about a numeric variable?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Normally, JavaScript expressions inserted in JSX will evaluate to a string, a React element, or a list of those things. […] — &lt;a href="https://reactjs.org/docs/jsx-in-depth.html#functions-as-children" rel="noopener noreferrer"&gt;React docs: JSX in Depth&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;React tries to convert results of your expressions into a string, React element or array. This is why you see &lt;code&gt;Invariant Violation: Text strings must be rendered within a &amp;lt;Text&amp;gt; component&lt;/code&gt; even if your variable was &lt;code&gt;Number&lt;/code&gt;. It may be misleading while searching for this bug in a production code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is it hard to find React Native conditional render error?
&lt;/h2&gt;

&lt;p&gt;This error is sneaky because it may take a long time before it shows up. You code may be working like a charm without any issues for months and suddenly something changes on API and type of that nullable variable changes suddenly to empty string or &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why it works with variables that are &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; then? It will also work for booleans. React creators make our life easier and by default such variables are ignored in a JSX tree. It is special case and it will not be rendered.&lt;/p&gt;

&lt;p&gt;React will also not crash when you put empty array directly into JSX as arrays can render multiple elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// below expressions will not crash your React Native app&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="kc"&gt;false&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="si"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  React for web — zero appears
&lt;/h3&gt;

&lt;p&gt;Developing a website in React and not converting variable into boolean will also break things but not as much as on native platform. For web empty string or 0 will be rendered. It is normal string and those can be rendered in HTML. For empty string it is usually missed and everything works well as nothing appears on the screen. It may be spotted when one try to conditionally render numeric variable as some strange 0 appears on the site. But nothing crashes and users are not upset as much.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to make conditional rendering safer?
&lt;/h2&gt;

&lt;p&gt;Just make sure to convert every variable into Boolean before using logical AND &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator.&lt;/p&gt;

&lt;p&gt;You can do it multiple ways:&lt;/p&gt;

&lt;h3&gt;
  
  
  Double negation — &lt;code&gt;!!dangerousData&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;It’s an easy quick fix that will work and some experiments says that it’s execution time is faster than &lt;code&gt;Boolean(dangerousData)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I do not recommend it though.&lt;/p&gt;

&lt;p&gt;This solution’s main pitfall is a human factor. Someone in your team could think that it is pointless to do double negation as it goes from &lt;code&gt;true -&amp;gt; false -&amp;gt; true&lt;/code&gt;. It may lead to “refactor” that will create potential crashes in the future as this error may not reveal itself at first. My number one principle while coding is readability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Classic conversion — &lt;code&gt;Boolean(dangerousData)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This seems readable but as I mentioned above some say that it is slower in execution time so make your own research and decide if it is OK for your particular case. We can find news that in modern browsers it is optimized. You may also use some transpilers to change it before it goes to final code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rethink components architecture.
&lt;/h3&gt;

&lt;p&gt;Maybe you don’t need as many conditional renders in the component. Every component should be small and have simplified logic as much as it can. I have seen many overly complicated components with nested conditional renders and believe me it’s not something easy to maintain as your code grows.&lt;/p&gt;

&lt;h4&gt;
  
  
  Use Element variable
&lt;/h4&gt;

&lt;p&gt;In simple components sometimes you can use trick from React documentation with &lt;code&gt;if&lt;/code&gt; and variable assignment preceding &lt;code&gt;return&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&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;'Hello there!'&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isVillain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&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="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;deepVoice&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;'General React'oni!'&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="k"&gt;return&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;message&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Component is a function (if else in render)
&lt;/h4&gt;

&lt;p&gt;In class components it would be — &lt;code&gt;render&lt;/code&gt; method is a function.&lt;/p&gt;

&lt;p&gt;In function, you can call &lt;code&gt;return&lt;/code&gt; inside &lt;code&gt;if&lt;/code&gt; statement and it will not execute further on. It will have the same result as with &lt;em&gt;Element variable&lt;/em&gt; above. We don’t need else here because when condition is satisfied execution will go on, otherwise it will be stopped on first render.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&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;isVillain&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="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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&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;deepVoice&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;'General React'oni!'&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;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;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="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;'Hello there!'&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;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Conditional (ternary) operator
&lt;/h4&gt;

&lt;p&gt;You can also use conditional operator (ternary expression) &lt;code&gt;condition ? passed : failed&lt;/code&gt; but be aware that nesting those will destroy readability of your code. My advice is to set up&lt;a href="https://eslint.org/docs/rules/no-nested-ternary" rel="noopener noreferrer"&gt;no-nested-ternary&lt;/a&gt; rule for ESLint otherwise your code can become this: &lt;code&gt;const thing = foo ? bar : baz === qux ? quxx : foobar;&lt;/code&gt; but with lots more of code because components rises very quick in amount of letters. Multiple elements inside nested ternary operator will make render complicated and unreadable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&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;isVillain&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="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;deepVoice&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;'General React'oni!'&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;'Hello there!'&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explaining the array example (from the introduction)
&lt;/h3&gt;

&lt;p&gt;Just to remind you I was showing this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dataEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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="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;Visible only when array is not empty&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;View&lt;/span&gt;&lt;span class="p"&gt;&amp;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 you understand that what really happens in above code is returning &lt;code&gt;length&lt;/code&gt; to directly into JSX. It happens when &lt;code&gt;length&lt;/code&gt; is &lt;em&gt;falsy&lt;/em&gt; and it comes from logical operator implementation.&lt;/p&gt;

&lt;p&gt;To simplify the example and make things more visible lets assume that &lt;code&gt;dataEntries.length&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt; and following &lt;code&gt;View&lt;/code&gt; with &lt;code&gt;Text&lt;/code&gt; component is &lt;code&gt;&amp;lt;Component /&amp;gt;&lt;/code&gt;. Now we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&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 expression returns &lt;code&gt;0&lt;/code&gt; which is converted to string &lt;code&gt;'0'&lt;/code&gt; and you can see it as an error in React Native or as an extra character on the web.&lt;/p&gt;

&lt;p&gt;The quickest fix possible is to &lt;strong&gt;make sure that we don’t depend on &lt;em&gt;falsy&lt;/em&gt; value but on boolean &lt;code&gt;false&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here are multiple fix scenarios:&lt;/p&gt;

&lt;h4&gt;
  
  
  Double negation
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;dataEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Classic conversion
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Inline condition
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;dataEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Ternary operator
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dataEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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;Component&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Refactor, rethink, make it safe
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;conditionalComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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;dataEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;conditionalComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you have other way to render on specific condition? Write it on &lt;a href="https://twitter.com/Koprowski_it/status/1254862220829196289" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or comments under this article. Let’s talk about your observations with this problem.&lt;/p&gt;

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

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



&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>8 convincing reasons why Nozbe is the best GTD to do list app</title>
      <dc:creator>Daniel Koprowski</dc:creator>
      <pubDate>Mon, 13 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/koprowski_it/8-convincing-reasons-why-nozbe-is-the-best-gtd-to-do-list-app-427d</link>
      <guid>https://dev.to/koprowski_it/8-convincing-reasons-why-nozbe-is-the-best-gtd-to-do-list-app-427d</guid>
      <description>&lt;p&gt;Over a year now I’m using Nozbe as core of my GTD system. This todo app became my productivity booster. Why am I stick with it after multiple attempts to use other products of this category? Read on to find out.&lt;/p&gt;

&lt;p&gt;First thing worth to notice is Nozbe’s multi-platform ability. You can use this to do list app on desktop - Windows, Mac, Linux, mobile - Android, iOS, iPad and web. Yes, there is official Nozbe for Linux package! They even have an app for Apple Watch.&lt;/p&gt;

&lt;p&gt;Nozbe has a free plan as well as a premium one.&lt;/p&gt;

&lt;p&gt;This article contains affiliate links - when you decide to &lt;a href="https://koprowski.it/nozbe" rel="noopener noreferrer"&gt;register to Nozbe&lt;/a&gt; please use link from this article, so you will get a &lt;strong&gt;free month of premium account&lt;/strong&gt; as a gift! Moreover, this way you let me know that this content is interesting and support this blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Mobile and desktop quick add widget
&lt;/h2&gt;

&lt;p&gt;Absolutely my top reason why I’m stick with Nozbe for longer. My previous to do app experience usually finished within few months of using. Simply adding a new task was too energy consuming.&lt;/p&gt;

&lt;p&gt;It takes single tap on mobile or one shortcut on desktop to see &lt;em&gt;quick add&lt;/em&gt; widget. It appears on top of your current window, so you can add task immediately when it pops into your head. &lt;em&gt;Shortcuts described below&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For iPhone and iPad you can use quick add directly in Spotlight search box. On Android I use widget on my main screen and it pops up Quick Add input field.&lt;/p&gt;

&lt;p&gt;It’s the fastest and best optimised way to add a task to a to-do app I have ever seen.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Nozbe hashtag syntax - stay focused on your work
&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%2Fyuua2pggib82b8rflgz3.jpg" 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%2Fyuua2pggib82b8rflgz3.jpg" alt="Nozbe GTD todo list app - hashtag syntax" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Second thing that makes my life easier and I especially love this as a programmer is a &lt;em&gt;hashtag syntax&lt;/em&gt;. Simply type task in a specific format and it is sorted, prioritised, commented, set due date and more… It limits the number of clicks you have to do to accomplish your goal - which is adding task to your system.&lt;/p&gt;

&lt;p&gt;Described above &lt;em&gt;quick add&lt;/em&gt; widget supports this syntax as well as main input field inside the app.&lt;/p&gt;

&lt;p&gt;Why do I like it? Because I don’t like when I’m forced to click, drag, select etc. form UI. It slows me down and distracts me from what I was going to do.&lt;/p&gt;

&lt;p&gt;For example assume that we want to add a task to publish this blog post and&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;set deadline to tomorrow,&lt;/li&gt;
&lt;li&gt;move it to a project “Blog”,&lt;/li&gt;
&lt;li&gt;setup time needed to 1h,&lt;/li&gt;
&lt;li&gt;add a category “Computer”,&lt;/li&gt;
&lt;li&gt;add a comment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It would be lots of clicking in &lt;em&gt;other&lt;/em&gt; apps. With hashtags, we can accomplish this with one liner: &lt;code&gt;Publish post about Nozbe #Blog #Tomorrow #1 h #Computer ## Remember to write something nice about hashtags&lt;/code&gt;. Nozbe autocompletes those keywords so user don’t need to remember any of this! You can type # and choose with arrows option that suits you best. Keyboard only!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://koprowski.it/nozbe" rel="noopener noreferrer"&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%2Fbuhlyey6toro7w5nm00f.png" alt="Nozbe the best GTD to do list app: affiliate banner" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Nozbe keyboard shortcuts
&lt;/h2&gt;

&lt;p&gt;Back for a while to the keyboard context. Here are useful keyboard shortcuts:&lt;/p&gt;

&lt;p&gt;Quick add task hotkey:&lt;br&gt;
You may need to enable it first in &lt;code&gt;Settings -&amp;gt; General&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows, Linux: &lt;code&gt;Ctrl+Shift+Space&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Mac: &lt;code&gt;Control+⌘+T&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Web: &lt;code&gt;Space&lt;/code&gt; - works only on app website&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create new task:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows, Linux: &lt;code&gt;Ctrl+N&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Mac: &lt;code&gt;⌘+N&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Web: &lt;code&gt;A&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Navigate through task list (helpful on weekly review):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use button/up arrows to select task&lt;/li&gt;
&lt;li&gt;use left/right to arrows to open/hide task details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mark task as done&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows, Linux: &lt;code&gt;Ctrl+D&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Mac: &lt;code&gt;⌘+D&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Missing shortcuts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I would like to use only keyboard but there are missing shortcuts - navigating through projects list and categories lists. With those shortcuts we could use keyboard only but until then we still need to use touchpad or mouse.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. To do list app for couples
&lt;/h2&gt;

&lt;p&gt;Shared list of tasks can improve your relationship. I’m not joking right now - using productivity tools and knowledge doesn’t need to narrow only for business purposes. We have started using &lt;a href="https://koprowski.it/nozbe" rel="noopener noreferrer"&gt;Nozbe&lt;/a&gt; for household tasks and it works amazing. Another example is planning a journey together when you divide some tasks between two of you.&lt;/p&gt;

&lt;p&gt;Creating a project “Home” with you and your partner as participants is natural and not interfere with your private projects. Simply “invite people” to desired project and that’s it. Both of you see only shared projects.&lt;/p&gt;

&lt;p&gt;Beware that it will limit excuses about “forgetting about something” so use this tool with caution! :)&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Push notifications with plan summary to prepare one day ahead
&lt;/h2&gt;

&lt;p&gt;Small, yet highly mobilizing feature. You can set up mobile app to send push notifications not only when task is going to happen next few minutes. Nothing is permanent - user can set according times or even disable those notifications.&lt;/p&gt;

&lt;p&gt;In the evening you can receive notification with tasks for next day to prepare your mind for upcoming challenges or modify it.&lt;/p&gt;

&lt;p&gt;Next summary notification can arrive in the morning with all tasks that you need to complete today. This is your ally. You can briefly plan this day in your mind with one look at notification or go into detail clicking on it.&lt;/p&gt;

&lt;p&gt;You can also think about sync with google calendar - it is a quick process and gives nice view for calendar planning. Consider setting up notifications properly to avoid double reminders. There is a special checkbox in Nozbe settings for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Community and productivity resources
&lt;/h2&gt;

&lt;p&gt;Nozbe is not only the app. It may be your whole productivity ecosystem if you let it.&lt;/p&gt;

&lt;p&gt;Creators of the app are people focused on productivity. They record podcast, write a blog, course, moderate facebook support groups, record youtube videos and more. There is a book about productivity! &lt;em&gt;(Book is described below)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I highly recommend not only download the app but also gain knowledge from creators about workflow with Nozbe or tasks in general. All functions are here for some reason and additional reading may give you “Aha!” moments that will change your way of dealing with to do lists.&lt;/p&gt;

&lt;p&gt;The materials that they create are universal. If you decide to switch to another app you will take the knowledge with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Book from the creator of Nozbe added to subscription
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com/gp/product/B07L43376J/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=B07L43376J&amp;amp;linkCode=as2&amp;amp;tag=koprowski05-20&amp;amp;linkId=faee7591c451eaf7f2cbe5d5bad20afe" rel="noopener noreferrer"&gt;10 Steps to Ultimate Productivity by Michael Sliwinski&lt;/a&gt;. This book is essential set of good productivity habits. I recommend reading it whether you are interested in the app or not.&lt;/p&gt;

&lt;p&gt;Book is quite short - my printed version has 145 pages full of content. No fillers just ready receipts to improve reader’s ability to have meaningful time.&lt;/p&gt;

&lt;p&gt;For me the best advice was “Step 8: Review your system regularly” with my favourite quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Weekly Review&lt;/em&gt; must be done at &lt;em&gt;least once a month&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It was so much fun to read this for the first time. Weekly reviews were a game changer for me. Previously it was like a single piece of puzzle that I was missing.&lt;/p&gt;

&lt;p&gt;I’m a big fan of productivity apps and I have experience with several of them. Usually those apps got stuffed with items and system was slowing me down. Then I was moving to another app - sometimes with exported tasks from previous one that never ended well.&lt;/p&gt;

&lt;p&gt;Answer to my problems was &lt;strong&gt;regular&lt;/strong&gt; review of the system and this book explained to me why it is so important. I highly recommend reading this chapter and the whole book for your own benefit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can get the book as a gift from Nozbe&lt;/strong&gt; when you decide to buy a paid subscription. I think it is the cheapest way of receiving the book.&lt;a href="https://koprowski.it/nozbe" rel="noopener noreferrer"&gt;Nozbe premium&lt;/a&gt; gives you unlimited number of projects, productivity reports and other goodies - when you decide to go premium you can feel the whole power of the program.&lt;/p&gt;

&lt;p&gt;You can also order only the book. Simply visit &lt;a href="https://www.amazon.com/gp/product/B07L43376J/ref=as_li_qf_asin_il_tl?ie=UTF8&amp;amp;tag=koprowski05-20&amp;amp;creative=9325&amp;amp;linkCode=as2&amp;amp;creativeASIN=B07L43376J&amp;amp;linkId=6595c4ff810d81cbdfa0250bcb9ca8c1" rel="noopener noreferrer"&gt;it’s Amazon listing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.amazon.com/gp/product/B07L43376J/ref=as_li_qf_asin_il_tl?ie=UTF8&amp;amp;tag=koprowski05-20&amp;amp;creative=9325&amp;amp;linkCode=as2&amp;amp;creativeASIN=B07L43376J&amp;amp;linkId=6595c4ff810d81cbdfa0250bcb9ca8c1" rel="noopener noreferrer"&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%2Fob1ltrhflfsw7pxiyib6.jpg" alt="10 Steps to Ultimate Productivity with Daniel Koprowski exlibris - Nozbe GTD" width="512" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. To-do app is not enough? Check Nozbe HOW templates!
&lt;/h2&gt;

&lt;p&gt;There is a mechanism of creating public project templates for others to use. It is called Nozbe HOW and is often used with hashtag &lt;strong&gt;#NozbeHOW&lt;/strong&gt; on Twitter. Great opportunity for content creators to engage the fans. For regular user - ready to do lists with common problems divided into easy steps.&lt;/p&gt;

&lt;p&gt;Examples? Here you go:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nozbe.how/vynaO" rel="noopener noreferrer"&gt;How to make Weekly Review - from Nozbe CEO&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://nozbe.how/waBhr" rel="noopener noreferrer"&gt;What your spouse needs from you every day&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nozbe.how/vphty" rel="noopener noreferrer"&gt;How to make a good code review&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Above examples are from the official Nozbe HOW website.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interested in the app?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://koprowski.it/nozbe" rel="noopener noreferrer"&gt;Register to Nozbe using my referral link and receive &lt;strong&gt;free ONE MONTH&lt;/strong&gt; of premium account!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>tools</category>
    </item>
    <item>
      <title>Organize your Unity project directories structure!</title>
      <dc:creator>Daniel Koprowski</dc:creator>
      <pubDate>Thu, 24 Mar 2016 23:00:00 +0000</pubDate>
      <link>https://dev.to/koprowski_it/organize-your-unity-project-directories-structure-13pp</link>
      <guid>https://dev.to/koprowski_it/organize-your-unity-project-directories-structure-13pp</guid>
      <description>&lt;p&gt;Organize your workplace! Unity devs do not dispose of any common solution for this issue. It’s time to change it.&lt;/p&gt;

&lt;p&gt;Work on multiple projects, together with many developers taught me that some general solutions have to be developed due to the fact that now most frequent pattern is a &lt;em&gt;mess&lt;/em&gt;. I have lost few hours of my life just because files were in the wrong place. One can think this is only cosmetic improvement or it can be done later. But this minor detail can improve your team work and save unnecessary confusion. &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%2Ft65lq6s6mkeo4l3mh608.jpg" 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%2Ft65lq6s6mkeo4l3mh608.jpg" alt="Unity project directories structure: Mess image" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep your files in proper directories
&lt;/h2&gt;

&lt;p&gt;This is where I could finish but… In Unity we get an empty &lt;code&gt;Assets&lt;/code&gt; folder so we can do and use it to whatever we want. That’s what I call freedom :) But be responsible!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bad idea: Put everything into this folder without any order.&lt;/li&gt;
&lt;li&gt;Good idea: Create some directory structure&lt;/li&gt;
&lt;li&gt;The best idea: Create universal structure where everything has its place&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  But how should I prepare such structure?
&lt;/h3&gt;

&lt;p&gt;Look at your last projects. Which files could be packed together? Which of them you had used most frequent?&lt;br&gt;&lt;br&gt;
Also think about your team. Solution should be intuitive for everyone.&lt;/p&gt;

&lt;p&gt;I mostly work on small projects - few scenes, few team members. For bigger games I would rather adjust files per scene/level or functionality. Despite this in my case the best directory structure is as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|- Assets
    |- Editor //special folder
    |- Resources //special folder
    |- Plugins //special folder
    |- Extensions
    |- Scenes
    |- Scripts
    |- StaticAssets
        |- Animations
        |- Animators
        |- Effects 
        |- Fonts
        |- Materials
        |- Models
        |- Prefabs
        |- Shaders
        |- Sounds
        |- Sprites
        |- Textures
        |- Videos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you have full list of so-called &lt;a href="http://docs.unity3d.com/Manual/SpecialFolders.html" rel="noopener noreferrer"&gt;Special Folders&lt;/a&gt;.We are using such order with my team from about year now and it works well. I don’t remember any situation that we needed to add some new folder &lt;em&gt;(of course we use some subfolders with this)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic solution
&lt;/h3&gt;

&lt;p&gt;Don’t worry. You don’t have to create all these folders manually. I’m creating few tools facilitating starting up with new project. One of them is &lt;a href="https://github.com/dkoprowski/UnityProjectTreeGenerator" rel="noopener noreferrer"&gt;Unity Project Tree Generator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This little plugin will generate mentioned directory structure in few moments. It will also add &lt;code&gt;.keep&lt;/code&gt; file to each folder just because &lt;code&gt;git&lt;/code&gt; ignores empty directories. If you have existing project with some structure created - it’s OK - it will only create new folders if you don’t have them. It will not edit or remove anything.&lt;/p&gt;

&lt;p&gt;Of course it is your project so you can change your directory tree as you want.To do this just look at &lt;code&gt;GenerateDirectory&lt;/code&gt; method in &lt;code&gt;CreateProjectTree&lt;/code&gt; class.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
      <category>csharp</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
