<?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>Forem: Dani Akash 🧪💥</title>
    <description>The latest articles on Forem by Dani Akash 🧪💥 (@dani_akash_).</description>
    <link>https://forem.com/dani_akash_</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%2F352416%2F3ddc44ba-11e9-4bec-8612-658af818f954.jpg</url>
      <title>Forem: Dani Akash 🧪💥</title>
      <link>https://forem.com/dani_akash_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dani_akash_"/>
    <language>en</language>
    <item>
      <title>GitHub Actions workflow for building &amp; managing React Native libraries</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Wed, 16 Sep 2020 10:39:15 +0000</pubDate>
      <link>https://forem.com/dani_akash_/github-actions-workflow-for-building-managing-react-native-libraries-3i63</link>
      <guid>https://forem.com/dani_akash_/github-actions-workflow-for-building-managing-react-native-libraries-3i63</guid>
      <description>&lt;h3&gt;
  
  
  My Workflow
&lt;/h3&gt;

&lt;p&gt;I built a workflow which will help React Native library maintainers to build &amp;amp; manage their library based on my experience in building libraries in my open-source organization &lt;a href="https://github.com/react-native-toolkit"&gt;React Native Toolkit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The workflows are currently used in two of my libraries,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/react-native-toolkit/react-native-better-image"&gt;React Native Better Image&lt;/a&gt; - &lt;a href="https://github.com/react-native-toolkit/react-native-better-image/tree/master/.github/workflows"&gt;workflow code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/react-native-toolkit/rex-state"&gt;Rex State&lt;/a&gt; - &lt;a href="https://github.com/react-native-toolkit/rex-state/tree/master/.github/workflows"&gt;workflow code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Maintainer Must-Haves&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a workflow to help maintainers of React Native JavaScript libraries. It can also be easily modified for React.js libraries too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Yaml File or Link to Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/react-native-toolkit"&gt;
        react-native-toolkit
      &lt;/a&gt; / &lt;a href="https://github.com/react-native-toolkit/react-native-better-image"&gt;
        react-native-better-image
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A better image component for react-native with fallback images &amp;amp; progressive loading support
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/react-native-toolkit/react-native-better-image/raw/master/assets/logo.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gGHHikP3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/react-native-toolkit/react-native-better-image/raw/master/assets/logo.png" alt="better-image-logo" height="150px" width="150px"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
React Native Better Image&lt;/h1&gt;
&lt;p&gt;A better image component for react-native with fallback images &amp;amp; progressive loading support&lt;/p&gt;
&lt;p&gt;Built on top of &lt;code&gt;View&lt;/code&gt;, &lt;code&gt;Image&lt;/code&gt; &amp;amp; &lt;code&gt;Animated&lt;/code&gt; components&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/react-native-toolkit/react-native-better-image/actions"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SzmrJRIl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/react-native-toolkit/react-native-better-image/workflows/build/badge.svg" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://codeclimate.com/github/react-native-toolkit/react-native-better-image/maintainability" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/9fe763e6f619a7478fc86582c86bca4c7c6d5ace/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f61636635323433643133303534326464653763392f6d61696e7461696e6162696c697479" alt="Maintainability"&gt;&lt;/a&gt;
&lt;a href="https://codeclimate.com/github/react-native-toolkit/react-native-better-image/test_coverage" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/ebbc54b07cc692b0dd6a5bfa5b51e7d78f494145/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f61636635323433643133303534326464653763392f746573745f636f766572616765" alt="Test Coverage"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/react-native-better-image" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/2cf7b67e4aa02304b842f84e198198b5be460d9a/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f72656163742d6e61746976652d6265747465722d696d6167652e737667" alt="Version"&gt;&lt;/a&gt;
&lt;a href="http://www.npmtrends.com/react-native-better-image" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/3de635891bea49a0f772867340e392f1b74159fe/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f72656163742d6e61746976652d6265747465722d696d6167652e737667" alt="Downloads"&gt;&lt;/a&gt;
&lt;a href="https://bundlephobia.com/result?p=react-native-better-image" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/0f7744fb3e31fecfdf1f20e071df898c46933c30/68747470733a2f2f62616467656e2e6e65742f62756e646c6570686f6269612f6d696e7a69702f72656163742d6e61746976652d6265747465722d696d616765" alt="Bundlephobia"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/react-native-toolkit/react-native-better-image/stargazers"&gt;&lt;img src="https://camo.githubusercontent.com/251ac0f2c4b8bdd49ca7c83320f13468cba6aefb/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f72656163742d6e61746976652d746f6f6c6b69742f72656163742d6e61746976652d6265747465722d696d6167652e7376673f7374796c653d736f6369616c" alt="Star on GitHub"&gt;&lt;/a&gt;
&lt;a href="https://github.com/react-native-toolkit/react-native-better-image/watchers"&gt;&lt;img src="https://camo.githubusercontent.com/75e059b24955a2413e3bb038e356ec1cf85274fb/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f77617463686572732f72656163742d6e61746976652d746f6f6c6b69742f72656163742d6e61746976652d6265747465722d696d6167652e7376673f7374796c653d736f6369616c" alt="Watch on GitHub"&gt;&lt;/a&gt;
&lt;a href="https://twitter.com/dani_akash_" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/f25542dcaef9a73a679cc32d059a2eca15927bc2/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f64616e695f616b6173685f3f7374796c653d736f6369616c" alt="Twitter Follow"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/daniakash" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/6800f7581c3470add582fce60348effa22ab4c21/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d2545322539382539352545462542382538462532306275792532306d6525323061253230636f666665652d653835623436" alt="donate"&gt;&lt;/a&gt;
&lt;a href="https://www.buymeacoffee.com/daniakash/e/6983" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/5a6c9c1eafd36496b7a8251ac01425c62342af09/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d25463025394625384625383525323073706f6e736f722532307468697325323070726f6a6563742d653835623436" alt="sponsor"&gt;&lt;/a&gt;
&lt;a href="https://www.buymeacoffee.com/daniakash/e/7030" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/eeaa572c5f419242fbbb97adaa73a514b57ea3d9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d476574253230537570706f72742d653835623436" alt="support"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://betterimage.netlify.app" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/4c64e07178937065fd61d9ba90de13291394dd56/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f73746f7279626f6f6b6a732f6272616e64406d61737465722f62616467652f62616467652d73746f7279626f6f6b2e737667" alt="Storybook"&gt;&lt;/a&gt; &lt;a href="https://chromatic.com/library?appId=5f5078c6fe7d0c0022c82f06&amp;amp;branch=master" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/b55ee52c26e7ddcb11e42e16c68a262a13dd5aa2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d6368726f6d617469632d253233666335323166" alt="Chromatic"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/react-native-toolkit/react-native-better-image/raw/master/assets/cover.gif"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xJz5JvP6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://github.com/react-native-toolkit/react-native-better-image/raw/master/assets/cover.gif" alt="better-image-cover"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
Compatible with Expo &amp;amp; React Native Web 🚀
&lt;/h3&gt;
&lt;h3&gt;
PRs Welcome 👍✨
&lt;/h3&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
📦 &lt;a href="https://raw.githubusercontent.com/react-native-toolkit/react-native-better-image/master/#installation"&gt;Installation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
ℹ️ &lt;a href="https://raw.githubusercontent.com/react-native-toolkit/react-native-better-image/master/#usage"&gt;Usage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
📃 &lt;a href="https://betterimage.netlify.app" rel="nofollow"&gt;Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
✨ &lt;a href="https://raw.githubusercontent.com/react-native-toolkit/react-native-better-image/master/#motivation"&gt;Motivation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
📱 &lt;a href="https://expo.io/@daniakash/react-native-better-image-example" rel="nofollow"&gt;Example App&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Installation&lt;/h2&gt;
&lt;div class="highlight highlight-source-shell"&gt;&lt;pre&gt;yarn add react-native-better-image
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt;or&lt;/span&gt;
npm install react-native-better-image&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
Usage&lt;/h2&gt;
&lt;div class="highlight highlight-source-js"&gt;&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-v"&gt;BetterImage&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'react-native-better-image'&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-c"&gt;// ...&lt;/span&gt;

&lt;span class="pl-c1"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;BetterImage&lt;/span&gt;
  &lt;span class="pl-c1"&gt;containerStyle&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;&lt;span class="pl-s1"&gt;style&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;
  &lt;span class="pl-c1"&gt;source&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-c1"&gt;uri&lt;/span&gt;: &lt;span class="pl-c"&gt;// image uri&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;
  &lt;span class="pl-c1"&gt;thumbnailSource&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-c1"&gt;uri&lt;/span&gt;: &lt;span class="pl-c"&gt;// thumbnail uri - will be displayed till image is loaded&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;
  &lt;span class="pl-c1"&gt;fallbackSource&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-c1"&gt;uri&lt;/span&gt;: &lt;span class="pl-c"&gt;// fallback image if original image fails to load&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;
  &lt;span class="pl-c"&gt;// ...all other react-native image props&lt;/span&gt;
/&lt;span class="pl-c1"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
Motivation&lt;/h2&gt;
&lt;p&gt;React Native only includes a basic image component. I used to try solutions like &lt;a href="https://github.com/DylanVann/react-native-fast-image"&gt;react-native-fast-image&lt;/a&gt; but none actually worked for…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/react-native-toolkit/react-native-better-image"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/react-native-toolkit"&gt;
        react-native-toolkit
      &lt;/a&gt; / &lt;a href="https://github.com/react-native-toolkit/rex-state"&gt;
        rex-state
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Convert hooks into shared states between React components
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/react-native-toolkit/rex-state/raw/master/assets/logo.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xdWZHuMQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/react-native-toolkit/rex-state/raw/master/assets/logo.png" alt="rex-state-logo" height="100px" width="100px"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
Rex State&lt;/h1&gt;
&lt;p&gt;Convert hooks into shared states between react components&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/react-native-toolkit/rex-state/actions"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nUxEjXV6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/react-native-toolkit/rex-state/workflows/build/badge.svg" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://codeclimate.com/github/react-native-toolkit/rex-state/maintainability" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/f8c5cbfe698c58955e0f6d1c85b4c10753e671eb/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f39626437373539303765636138613364626162332f6d61696e7461696e6162696c697479" alt="Maintainability"&gt;&lt;/a&gt;
&lt;a href="https://codeclimate.com/github/react-native-toolkit/rex-state/test_coverage" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/46574baa5027e896ff685508c43b3e36d28dd355/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f39626437373539303765636138613364626162332f746573745f636f766572616765" alt="Test Coverage"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/rex-state" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/7f17c83a6d823ac8c598df946cbebd0e56a19213/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f7265782d73746174652e737667" alt="Version"&gt;&lt;/a&gt;
&lt;a href="http://www.npmtrends.com/rex-state" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/050891852804285313398689b17a66ec88af4501/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f7265782d73746174652e737667" alt="Downloads"&gt;&lt;/a&gt;
&lt;a href="https://bundlephobia.com/result?p=rex-state" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/875696ec2730c84c2f8edc09ba936a0966888444/68747470733a2f2f62616467656e2e6e65742f62756e646c6570686f6269612f6d696e7a69702f7265782d7374617465" alt="Bundlephobia"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/DaniAkash/rex/stargazers"&gt;&lt;img src="https://camo.githubusercontent.com/ec8c30316d75759d42b8a433809d902f8956017f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f44616e69416b6173682f7265782e7376673f7374796c653d736f6369616c" alt="Star on GitHub"&gt;&lt;/a&gt;
&lt;a href="https://github.com/DaniAkash/rex/watchers"&gt;&lt;img src="https://camo.githubusercontent.com/401ab7eb104fa04efd52d73a062f1f9c41e5039c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f77617463686572732f44616e69416b6173682f7265782e7376673f7374796c653d736f6369616c" alt="Watch on GitHub"&gt;&lt;/a&gt;
&lt;a href="https://twitter.com/dani_akash_" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/f25542dcaef9a73a679cc32d059a2eca15927bc2/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f64616e695f616b6173685f3f7374796c653d736f6369616c" alt="Twitter Follow"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/daniakash" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/6800f7581c3470add582fce60348effa22ab4c21/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d2545322539382539352545462542382538462532306275792532306d6525323061253230636f666665652d653835623436" alt="donate"&gt;&lt;/a&gt;
&lt;a href="https://www.buymeacoffee.com/daniakash/e/6983" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/5a6c9c1eafd36496b7a8251ac01425c62342af09/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d25463025394625384625383525323073706f6e736f722532307468697325323070726f6a6563742d653835623436" alt="sponsor"&gt;&lt;/a&gt;
&lt;a href="https://www.buymeacoffee.com/daniakash/e/7030" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/eeaa572c5f419242fbbb97adaa73a514b57ea3d9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d476574253230537570706f72742d653835623436" alt="support"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://rex-state.netlify.app" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/4c64e07178937065fd61d9ba90de13291394dd56/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f73746f7279626f6f6b6a732f6272616e64406d61737465722f62616467652f62616467652d73746f7279626f6f6b2e737667" alt="Storybook"&gt;&lt;/a&gt; &lt;a href="https://chromatic.com/library?appId=5f5b21fe6f304800225bd9cf&amp;amp;branch=master" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/b55ee52c26e7ddcb11e42e16c68a262a13dd5aa2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d6368726f6d617469632d253233666335323166" alt="Chromatic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
PRs Welcome 👍✨
&lt;/h3&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
📦 &lt;a href="https://raw.githubusercontent.com/react-native-toolkit/rex-state/master/#installation"&gt;Installation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
ℹ️ &lt;a href="https://raw.githubusercontent.com/react-native-toolkit/rex-state/master/#usage"&gt;Usage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
📑 &lt;a href="https://rex-state.netlify.app" rel="nofollow"&gt;Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👨🏽‍🏫 Examples
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://codesandbox.io/s/rex-counter-2m4zy?file=/src/App.js" rel="nofollow"&gt;Simple Counter&lt;/a&gt; with React.js on CodeSandbox&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://expo.io/@daniakash/rex-state-example" rel="nofollow"&gt;Dark Mode&lt;/a&gt; with React Native on expo. Project in &lt;a href="https://github.com/react-native-toolkit/rex-state/tree/master/example"&gt;&lt;code&gt;example/&lt;/code&gt;&lt;/a&gt; directory&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
✨ &lt;a href="https://raw.githubusercontent.com/react-native-toolkit/rex-state/master/#why-rex-state"&gt;Why Rex State?&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Requirements&lt;/h2&gt;
&lt;p&gt;Rex State is built purely on React Hooks hence it requires React &amp;gt; 16.8 to work.&lt;/p&gt;
&lt;h2&gt;
Installation&lt;/h2&gt;
&lt;div class="highlight highlight-source-shell"&gt;&lt;pre&gt;yarn add rex-state
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or&lt;/span&gt;
npm i rex-state&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
Usage&lt;/h2&gt;
&lt;p&gt;Consider the following hook which lets you toggle theme between light &amp;amp; dark modes&lt;/p&gt;
&lt;div class="highlight highlight-source-js-jsx"&gt;&lt;pre&gt;&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-en"&gt;useThemeMode&lt;/span&gt; &lt;span class="pl-k"&gt;=&lt;/span&gt; (&lt;span class="pl-smi"&gt;initialTheme&lt;/span&gt; &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;light&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span class="pl-k"&gt;=&amp;gt;&lt;/span&gt; {
  &lt;span class="pl-k"&gt;const&lt;/span&gt; [&lt;span class="pl-smi"&gt;theme&lt;/span&gt;, &lt;span class="pl-smi"&gt;setTheme&lt;/span&gt;] &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-en"&gt;useState&lt;/span&gt;(&lt;span class="pl-smi"&gt;initialTheme&lt;/span&gt;)
  &lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-en"&gt;toggleTheme&lt;/span&gt; &lt;span class="pl-k"&gt;=&lt;/span&gt; () &lt;span class="pl-k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pl-en"&gt;setTheme&lt;/span&gt;(&lt;span class="pl-smi"&gt;theme&lt;/span&gt; &lt;span class="pl-k"&gt;===&lt;/span&gt; &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;light&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="pl-k"&gt;?&lt;/span&gt; &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;dark&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="pl-k"&gt;:&lt;/span&gt; &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;light&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt;);

  &lt;span class="pl-k"&gt;return&lt;/span&gt; [&lt;span class="pl-smi"&gt;theme&lt;/span&gt;, &lt;span class="pl-smi"&gt;toggleTheme&lt;/span&gt;];
};&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can use the &lt;code&gt;createRexStore&lt;/code&gt; module from rex state to create a provider &amp;amp; a…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/react-native-toolkit/rex-state"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;I have written detailed posts on how to use these workflows in the DEV Community ﹣&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/dani_akash_/getting-started-with-your-react-native-library-3c3a"&gt;Getting started with your React Native library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/dani_akash_/automating-your-react-native-library-s-build-process-ml3"&gt;Automating your React Native library's build process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/dani_akash_/automating-the-review-process-of-your-react-native-library-s-prs-4457"&gt;Automating the review process of your React Native Library's PRs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/dani_akash_/automatically-publish-an-update-to-npm-when-you-create-a-release-in-github-464f"&gt;Automatically publish an update to NPM when you create a release in GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>actionshackathon</category>
    </item>
    <item>
      <title>Automatically publish an update to NPM when you create a release in GitHub</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Wed, 16 Sep 2020 10:22:27 +0000</pubDate>
      <link>https://forem.com/dani_akash_/automatically-publish-an-update-to-npm-when-you-create-a-release-in-github-464f</link>
      <guid>https://forem.com/dani_akash_/automatically-publish-an-update-to-npm-when-you-create-a-release-in-github-464f</guid>
      <description>&lt;p&gt;In my &lt;a href="https://dev.to/dani_akash_/automating-the-review-process-of-your-react-native-library-s-prs-4457"&gt;last blog post&lt;/a&gt;, we created a workflow for reviewing Pull Requests. This is the final part of the series where we'll set up a workflow to automatically push updates to our package on NPM every time we create a new release in GitHub.&lt;/p&gt;

&lt;p&gt;This workflow is used in the &lt;a href="https://github.com/react-native-toolkit/rex-state/blob/master/.github/workflows/publish.yml"&gt;.github/workflows/publish.yml&lt;/a&gt; file of my library &lt;a href="https://github.com/react-native-toolkit/rex-state/"&gt;rex-state&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Releases
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/react-native-toolkit/rex-state/releases"&gt;Releases&lt;/a&gt; section allows us to tag individual commits with proper version numbers &amp;amp; a detailed changelog.&lt;/p&gt;

&lt;p&gt;I use it as my source of truth for managing versions. Which means, every tag should be automatically published to GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trigger
&lt;/h2&gt;

&lt;p&gt;This workflow will run on &lt;code&gt;release&lt;/code&gt; when the the type is &lt;code&gt;published&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;publish&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;published&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Jobs
&lt;/h2&gt;

&lt;p&gt;This workflow has three jobs. First two are &lt;strong&gt;linting&lt;/strong&gt; &amp;amp; &lt;strong&gt;testing&lt;/strong&gt; to ensure the code is stable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lint&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12.x&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn typescript&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn lint&lt;/span&gt;

  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;macOS-latest&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
        &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;12.x'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test/node ${{ matrix.node }}/${{ matrix.platform }}&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.platform }}&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.node }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once the above two jobs are over, we'll now use the &lt;a href="https://github.com/JS-DevTools/npm-publish"&gt;JS-DevTools/npm-publish&lt;/a&gt; Action to publish an update to NPM.&lt;/p&gt;

&lt;p&gt;You need to create an &lt;a href="https://docs.npmjs.com/creating-and-viewing-authentication-tokens"&gt;NPM Auth token&lt;/a&gt; and add it to your repository or organization secret under the name &lt;code&gt;NPM_TOKEN&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then add the publish the job to your workflow ﹣&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;publish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish to npm 🚢📦&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12.x&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JS-DevTools/npm-publish@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NPM_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Whenever you create a release in your repository from now onwards, you'll have an update published to your npm package.&lt;/p&gt;

&lt;p&gt;This completes our React Native Library setup, you can use the setup + workflows you learnt in this 4 part series to publish both your React Native &amp;amp; React.js libraries.&lt;/p&gt;

&lt;p&gt;I have been using it for both &lt;a href="https://github.com/react-native-toolkit/react-native-better-image/"&gt;react-native-better-image&lt;/a&gt; which is for React Native &amp;amp; &lt;a href="https://github.com/react-native-toolkit/rex-state"&gt;rex-state&lt;/a&gt; which works with both React.js &amp;amp; React Native.&lt;/p&gt;

&lt;p&gt;In future, I'll be moving all my libraries in &lt;a href="https://github.com/react-native-toolkit"&gt;React Native Toolkit&lt;/a&gt; to this workflow which will help me maintain all my current 10+ libraries &amp;amp; some upcoming ones efficiently.&lt;/p&gt;

&lt;p&gt;If this series helped you or you have any feedback feel free to post a comment or reach out to me on &lt;a href="https://twitter.com/dani_akash_"&gt;twitter&lt;/a&gt;. I'd be happy to help! :D&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>actionshackathon</category>
      <category>github</category>
    </item>
    <item>
      <title>Automating the review process of your React Native Library's PRs</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Wed, 16 Sep 2020 08:54:57 +0000</pubDate>
      <link>https://forem.com/dani_akash_/automating-the-review-process-of-your-react-native-library-s-prs-4457</link>
      <guid>https://forem.com/dani_akash_/automating-the-review-process-of-your-react-native-library-s-prs-4457</guid>
      <description>&lt;p&gt;In my last &lt;a href="https://dev.to/dani_akash_/automating-your-react-native-library-s-build-process-ml3"&gt;blog post&lt;/a&gt; we saw how to automate the build process of your React Native library.&lt;/p&gt;

&lt;p&gt;Reviewing PRs are an important part of managing Open Source libraries. However, they might require a considerable amount of time &amp;amp; effort from your busy life which means, you need to be as efficient as possible.&lt;/p&gt;

&lt;p&gt;My whole toolchain was set up around making the review process as easy as possible. This time we'll create Github Action workflows to make the review process a whole lot simpler.&lt;/p&gt;

&lt;p&gt;Every PR raised to the library will have the following checks performed automatically&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linting &amp;amp; Testing&lt;/li&gt;
&lt;li&gt;Code coverage report&lt;/li&gt;
&lt;li&gt;Deploy preview of the updated storybook docs&lt;/li&gt;
&lt;li&gt;Build a review version of the example mobile app with link to quickly test it&lt;/li&gt;
&lt;li&gt;Send all stories to chromatic to do a visual review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As soon as the PR is sent, you should be able to see the progress of the review workflow ﹣&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/react-native-toolkit/rex-state/"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7viT8hhy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wsb1h67wn2sphq6fyrfc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above image is from a PR of my &lt;a href="https://github.com/react-native-toolkit/rex-state/"&gt;rex-state&lt;/a&gt; library. Let's look into how we can implement this effectively.&lt;/p&gt;

&lt;p&gt;You can find my working review workflow at &lt;a href="https://github.com/react-native-toolkit/rex-state/blob/master/.github/workflows/review.yml"&gt;.github/workflows/review.yml&lt;/a&gt; file of my &lt;a href="https://github.com/react-native-toolkit/rex-state/"&gt;rex-state&lt;/a&gt; library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Triggering the workflow
&lt;/h2&gt;

&lt;p&gt;This workflow will run on all pull requests&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;review&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pull_request&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Linting &amp;amp; Testing
&lt;/h2&gt;

&lt;p&gt;This step is the same as what we did for our build workflow. All the other jobs will run only after Linting &amp;amp; Testing are complete.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lint&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12.x&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn typescript&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn lint&lt;/span&gt;

  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;macOS-latest&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
        &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;12.x'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test/node ${{ matrix.node }}/${{ matrix.platform }}&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.platform }}&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.node }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Coverage report
&lt;/h2&gt;

&lt;p&gt;Previously on the build step, we used Code Climate to store our test coverage reports. However, on PRs we need a way to quickly check the test coverage for the incoming code.&lt;/p&gt;

&lt;p&gt;For this, we can use the &lt;a href="https://github.com/romeovs/lcov-reporter-action"&gt;romeovs/lcov-reporter-action&lt;/a&gt; which will post a nice comment on the PR with the test coverage details. You'd get a report like this following comment ﹣&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---gk5jSJy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yt8w4066hnph7y72onxu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---gk5jSJy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yt8w4066hnph7y72onxu.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the following configuration for receiving the coverage as a comment ﹣&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;coverage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coverage&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12.x&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn test --coverage&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;romeovs/lcov-reporter-action@v0.2.16&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;github-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Deploy preview of the updated storybook docs
&lt;/h2&gt;

&lt;p&gt;Since I was using the Netlify Github App, I'm getting the deploy previews out of the box without any kind of additional setup. You can try the &lt;a href="https://docs.netlify.com/cli/get-started/"&gt;Netlify CLI&lt;/a&gt; if you want to manually enable deploy previews with Github Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review Version of the Example App
&lt;/h2&gt;

&lt;p&gt;This is where the power of expo toolchain shines. You can use the expo-cli to publish the app in a separate channel which you can use for your review purpose.&lt;/p&gt;

&lt;p&gt;The expo team have also provided detailed &lt;a href="https://github.com/expo/expo-github-action#test-prs-and-publish-a-review-version"&gt;documentation&lt;/a&gt; on their &lt;a href="https://github.com/expo/expo-github-action"&gt;expo-github-action&lt;/a&gt;. Add the following configuration to your workflow (replace the URL in the &lt;code&gt;msg&lt;/code&gt; with your application's URL)﹣&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;expo-publish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish to Expo 🚀&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12.x&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;expo/expo-github-action@v5&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;expo-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.x&lt;/span&gt;
          &lt;span class="na"&gt;expo-username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.EXPO_CLI_USERNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;expo-password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.EXPO_CLI_PASSWORD }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;expo publish --release-channel=pr-${{ github.event.number }}&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unsplash/comment-on-pr@master&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;App is ready for review, you can [see it here](https://expo.io/@daniakash/rex-state-example?release-channel=pr-${{ github.event.number }}).&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;From now on, for every PRs you'll get a comment just like this one ﹣&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O_VBRKLb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2aqycdostgrpbbwy9j7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O_VBRKLb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2aqycdostgrpbbwy9j7w.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Sending stories to chromatic
&lt;/h2&gt;

&lt;p&gt;Finally to do a visual review if the PR has affected your stories you can send the stories to chromatic. The configuration is the same as our last one, chromatic is smart enough to figure out that the data is from a PR!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;chromatic&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish storybook to chromatic 🧪&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12.x&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn chromatic&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;CHROMATIC_PROJECT_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.CHROMATIC_PROJECT_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once you have everything ready, Your PRs will now have detailed information on the things you'd otherwise have to check manually every time ﹣&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Awfb515P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dpqby0r6lxqnrctqg9af.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Awfb515P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dpqby0r6lxqnrctqg9af.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We got a powerful review workflow now. In the &lt;a href="https://dev.to/dani_akash_/automatically-publish-an-update-to-npm-when-you-create-a-release-in-github-464f"&gt;next blog post&lt;/a&gt;, let's publish the library to NPM every time you create a new release in GitHub!&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>actionshackathon</category>
      <category>github</category>
    </item>
    <item>
      <title>Getting started with your React Native library</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Wed, 16 Sep 2020 03:44:30 +0000</pubDate>
      <link>https://forem.com/dani_akash_/getting-started-with-your-react-native-library-3c3a</link>
      <guid>https://forem.com/dani_akash_/getting-started-with-your-react-native-library-3c3a</guid>
      <description>&lt;p&gt;React Native is an excellent framework for building mobile apps. The best thing about React Native is how it provides the developers with a solid set of primitive UI components. This means there's plenty of opportunities for you to build your own library and publish it to the open-source community.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Building &amp;amp; maintaining quality open-source libraries is hard work. Especially React Native libraries are harder since they often need to be verified on both Android &amp;amp; iOS platforms.&lt;/p&gt;

&lt;p&gt;I ran into this exact issue when I started working on open-sourcing the libraries I built for my personal use. I created an organization that holds the collection of the libraries. It's called &lt;a href="https://github.com/react-native-toolkit"&gt;React Native Toolkit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yfpNw-3u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mkjmd1mjy18bwm83406a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yfpNw-3u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mkjmd1mjy18bwm83406a.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wanted to ensure developers get to try out all my libraries, at the same time, I should be able to quickly make small updates and bug fixes without having to spend too much time.&lt;/p&gt;

&lt;p&gt;In summary, I wanted to ensure I covered all the following &lt;strong&gt;6 items&lt;/strong&gt; for my open-source libraries,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proper Linting of code &amp;amp; commit messages&lt;/li&gt;
&lt;li&gt;A working example in an actual app&lt;/li&gt;
&lt;li&gt;Unit tests&lt;/li&gt;
&lt;li&gt;Detailed documentation that covers all the use cases&lt;/li&gt;
&lt;li&gt;Visual testing after code changes&lt;/li&gt;
&lt;li&gt;Easily review PRs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Once I have created a list of things needed for my open source projects, I started exploring various tools that'll help me achieve the individual targets.&lt;/p&gt;

&lt;p&gt;So I started working on my library &lt;a href="https://github.com/react-native-toolkit/react-native-better-image"&gt;react-native-better-image&lt;/a&gt; while evaluating the various options. I had two major tasks&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Picking the right tools&lt;/li&gt;
&lt;li&gt;Automate as many tasks as possible&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Picking the right tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/react-native-community/bob"&gt;React Native Community's Bob&lt;/a&gt; - Linting + Example App
&lt;/h3&gt;

&lt;p&gt;This almost felt like a no-brainer. &lt;a href="https://github.com/react-native-community"&gt;React Native Community&lt;/a&gt; which hosts a collection of quality libraries already had a tool which would make building react native libraries so much simpler.&lt;/p&gt;

&lt;p&gt;Bob had &lt;a href="https://github.com/react-native-community/bob#scaffold-new-projects"&gt;almost everything&lt;/a&gt; I needed in terms of &lt;strong&gt;Proper Linting&lt;/strong&gt; &amp;amp; &lt;strong&gt;having a working example app&lt;/strong&gt; using the library. &lt;/p&gt;

&lt;p&gt;The example app is also pre-linked with the library's source so you can just start writing code and you probably won't have to worry about anything. Just import your library inside the app &amp;amp; setup your working example!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That's 2 out of 6 items covered&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Alternatives
&lt;/h4&gt;

&lt;p&gt;One other alternative I tried in this category is &lt;a href="https://github.com/brodybits/create-react-native-module"&gt;create-react-native-module&lt;/a&gt;. This one is good but bob is just too better.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://callstack.github.io/react-native-testing-library"&gt;React Native Testing Library&lt;/a&gt; - Unit Tests
&lt;/h3&gt;

&lt;p&gt;I'm a big fan of the &lt;strong&gt;&lt;a href="https://testing-library.com/"&gt;testing library&lt;/a&gt;&lt;/strong&gt; in general. It encourages you to write tests in the way your software is being used rather than being implemented. Which is why I immediately picked up the &lt;strong&gt;React Native Testing Library&lt;/strong&gt; that brings all the best parts to the native side of development.&lt;/p&gt;

&lt;p&gt;If your library uses native iOS or Android code, then you'll have to write tests that run on the native side. However, since all my libraries are pure JavaScript, I didn't explore any on the native side. &lt;em&gt;Suggest the tools you use for this purpose in the comments :)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That's 3 out of 6 items covered&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Alternatives
&lt;/h4&gt;

&lt;p&gt;If your library requires an end to end testing, then you can add &lt;a href="https://github.com/wix/Detox"&gt;detox&lt;/a&gt; to your project. You can use the example app created by Bob to run the test cases.&lt;/p&gt;

&lt;p&gt;Another common library for writing unit tests is &lt;a href="https://enzymejs.github.io/enzyme/docs/guides/react-native.html"&gt;Enzyme&lt;/a&gt;. If you are already familiar with enzyme then you can use it for your library.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://storybook.js.org/"&gt;Storybook&lt;/a&gt; - Documentation
&lt;/h3&gt;

&lt;p&gt;Storybook v6.0 was recently released with &lt;strong&gt;improved documentation&lt;/strong&gt;. While storybook already has a React Native version, the react version is much more powerful &amp;amp; better suited for our documentation.&lt;/p&gt;

&lt;p&gt;The documentation can be hosted a static site &amp;amp; it will showcase your library in real-time. Check out my &lt;a href="https://betterimage.netlify.app"&gt;react-native-better-image&lt;/a&gt; documentation.&lt;/p&gt;

&lt;p&gt;To get storybook working with your React Native library, you can add it to your &lt;strong&gt;example expo app&lt;/strong&gt; following &lt;a href="https://github.com/expo/examples/tree/master/with-storybook"&gt;this example&lt;/a&gt; from the expo team.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I only had to change the webpack config in my &lt;a href="https://github.com/react-native-toolkit/rex-state/blob/master/example/.storybook/main.js#L5"&gt;.storybook/main.js&lt;/a&gt; file and it worked well using react-native-web&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;4 out of 6 now covered&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Alternatives
&lt;/h3&gt;

&lt;p&gt;I haven't personally tried any alternatives to storybook yet. Maybe you can read about it in this &lt;a href="https://blog.logrocket.com/alternatives-to-react-storybook/"&gt;blog post&lt;/a&gt; by logrocket.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.chromatic.com/"&gt;Chromatic&lt;/a&gt; - Visual Testing
&lt;/h3&gt;

&lt;p&gt;One other reason I was firmly sticking to storybooks is their integration with chromatic. Chromatic lets you quickly do visual tests on your stories. You can also easily share stories &amp;amp; get feedback from others.&lt;/p&gt;

&lt;p&gt;They have a generous free tier &amp;amp; their team is kind enough to provide me support when I ran into issues with my react-native + storybook setup. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'll be using chromatic for reviewing PRs, will explain about it in the automation section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Chromatic makes visual testing a breeze! &lt;em&gt;That makes 5 out of 6 items handled&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://docs.expo.io/workflow/expo-cli/"&gt;Expo Cli&lt;/a&gt; - Reviewing PRs
&lt;/h3&gt;

&lt;p&gt;Reviewing PRs is the most important thing in Open Source projects. I have been struggling to review PRs in some of my old projects as I have to manually clone &amp;amp; run the code to check how it affects my library. Many times I just don't have the bandwidth to do so...&lt;/p&gt;

&lt;p&gt;This time, however, I have decided to make the reviewing process as easy as possible. The trick is to have a good example application in your library that covers almost all use cases. Once someone raises a PR, you can generate a build using the Expo CLI. Expo team has been making this process a lot easier by creating a &lt;a href="https://github.com/expo/expo-github-action#test-prs-and-publish-a-review-version"&gt;Github Action&lt;/a&gt; that can easily publish a review version of your library.&lt;/p&gt;

&lt;p&gt;Along with this, the stories in the PR are also pushed to chromatic. This means I should be able to review a PR fairly faster. I haven't yet received any PRs yet, so fingers crossed 🤞&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating stuff with Github Actions
&lt;/h2&gt;

&lt;p&gt;Now that we have all the right tools in place, it is time to automate the Build, Review &amp;amp; Publishing process for your new React Native library. Which will be covered in the &lt;a href="https://dev.to/dani_akash_/automating-your-react-native-library-s-build-process-ml3"&gt;next part of this series&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>Automating your React Native library's build process</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Tue, 15 Sep 2020 10:10:24 +0000</pubDate>
      <link>https://forem.com/dani_akash_/automating-your-react-native-library-s-build-process-ml3</link>
      <guid>https://forem.com/dani_akash_/automating-your-react-native-library-s-build-process-ml3</guid>
      <description>&lt;p&gt;In my &lt;a href="https://dev.to/dani_akash_/getting-started-with-your-react-native-library-3c3a"&gt;last blog post&lt;/a&gt;, I explained about the tools we will be using for your react native library. We are now going to automate the build process.&lt;/p&gt;

&lt;p&gt;All open-source Github repositories have free Github Actions available with which we can automate most of our workflows. I'll be using Github Actions throughout the automation process. &lt;/p&gt;

&lt;p&gt;The library's build consists of the following items ﹣&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linting&lt;/li&gt;
&lt;li&gt;Running Tests&lt;/li&gt;
&lt;li&gt;Publishing the test coverage&lt;/li&gt;
&lt;li&gt;Publishing the example app to expo&lt;/li&gt;
&lt;li&gt;Publishing the stories to chromatic&lt;/li&gt;
&lt;li&gt;Publish the storybook which contains documentation as a static site&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find my build workflow in the &lt;a href="https://github.com/react-native-toolkit/react-native-better-image/blob/master/.github/workflows/build.yml"&gt;.github/workflows/build.yml&lt;/a&gt; file of my &lt;a href="https://github.com/react-native-toolkit/react-native-better-image"&gt;react-native-better-image&lt;/a&gt; project. This is how the build process should look like ﹣&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DDeA85W3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o0kep5llpseapcik3fme.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DDeA85W3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/o0kep5llpseapcik3fme.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When to trigger the workflow
&lt;/h2&gt;

&lt;p&gt;I wanted the build workflow to ensure the master branch is always stable. Hence it will run on all the pushes to master. But it will not run for tags, as I have planned another release workflow for this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
    &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;!*'&lt;/span&gt; &lt;span class="c1"&gt;# Do not execute on tags&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;example/*&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/*&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test/*&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;__tests__/*&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;*.json'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;yarn.lock&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.github/**/*.yml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Linting
&lt;/h2&gt;

&lt;p&gt;Since we are using &lt;a href="https://github.com/react-native-community/bob"&gt;react-native-community/bob&lt;/a&gt; in our project, we can run both lint &amp;amp; typescript scripts in the &lt;code&gt;package.json&lt;/code&gt; file which is enough to complete the lint process&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lint&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12.x&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn typescript&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn lint&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing &amp;amp; Coverage
&lt;/h2&gt;

&lt;p&gt;For displaying the test coverage, I decided to use &lt;a href="https://codeclimate.com/oss/"&gt;code climate for open source projects&lt;/a&gt;. They also have a nice action available at &lt;a href="https://github.com/paambaati/codeclimate-action"&gt;paambaati/codeclimate-action&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Code climate checks your code for best practices and provides you with maintainability metrics. Along with that, you'll also get code coverage reports. Once you setup code climate you can add their badges to your repo that gives everyone a live code quality score ﹣&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/react-native-toolkit/rex-state"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---xD-KGLo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9czp25bmkrhieeljgqpc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following configuration is used for running tests ﹣&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;macOS-latest&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
        &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;12.x'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test/node ${{ matrix.node }}/${{ matrix.platform }}&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.platform }}&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ matrix.node }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once both linting &amp;amp; testing jobs are completed, you have to push your code coverage to code climate. Following their &lt;a href="https://docs.codeclimate.com/docs/github-actions-test-coverage"&gt;docs&lt;/a&gt; you need to create a &lt;a href="https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets"&gt;secret&lt;/a&gt; in your repository with name &lt;code&gt;CC_TEST_REPORTER_ID&lt;/code&gt; after which add the following configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;coverage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coverage&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@master&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12.x&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;paambaati/codeclimate-action@v2.5.3&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;CC_TEST_REPORTER_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.CC_TEST_REPORTER_ID}}&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;coverageCommand&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn test --coverage&lt;/span&gt;
          &lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Publish example app to expo
&lt;/h2&gt;

&lt;p&gt;Publish should also happen after the lint &amp;amp; test jobs. This time we will be using the &lt;a href="https://github.com/expo/expo-github-action"&gt;expo/expo-github-action&lt;/a&gt;. As per the action's &lt;a href="https://github.com/expo/expo-github-action"&gt;docs&lt;/a&gt;, you'll have to add your expo username &amp;amp; password to your repo's secrets under the name &lt;code&gt;EXPO_CLI_USERNAME&lt;/code&gt; &amp;amp; &lt;code&gt;EXPO_CLI_PASSWORD&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have an organization, you can add it under the &lt;a href="https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-an-organization"&gt;organization secrets&lt;/a&gt; and share it with all your repositories!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first step to publish is to run &lt;code&gt;yarn bootstrap&lt;/code&gt; command. However, the next step &lt;code&gt;expo run&lt;/code&gt; should run inside the &lt;code&gt;example&lt;/code&gt; directory. For this we will use the &lt;code&gt;working-directory&lt;/code&gt; config&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;publish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish example app to Expo 🚀&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12.x&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;expo/expo-github-action@v5&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;expo-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.x&lt;/span&gt;
          &lt;span class="na"&gt;expo-username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.EXPO_CLI_USERNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;expo-password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.EXPO_CLI_PASSWORD }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;expo publish&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You'll get a published page for your library's example app. You can check out for the page of my react-native-better-image library's &lt;a href="https://expo.io/@daniakash/react-native-better-image-example"&gt;example app&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publish stories to chromatic
&lt;/h2&gt;

&lt;p&gt;Similar to expo, chromatic also have a GitHub action available in &lt;a href="https://github.com/chromaui/action"&gt;chromaui/action&lt;/a&gt;. You have to create a new project in chromatic and get your project token. Then add it to your repository's secrets under the name &lt;code&gt;CHROMATIC_PROJECT_TOKEN&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We need to run chromatic action inside the example directory since our storybook lives in this directory. The chromaui/action didn't have an option to run it inside a specific directory. So I had to manually add the following script in my example app's &lt;code&gt;package.json&lt;/code&gt; file ﹣&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"chromatic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx chromatic"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then added the following workflow configuration which manually runs chromatic ﹣&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;chromatic&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish storybook to chromatic 🧪&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;12.x&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn bootstrap&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx yarn chromatic&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;CHROMATIC_PROJECT_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.CHROMATIC_PROJECT_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Publish storybook as a static site
&lt;/h2&gt;

&lt;p&gt;I used Netlify to publish my storybook as a static site. I was initially planning to use GH Pages, but I needed the 1-click rollback &amp;amp; Deploy Previews offered by &lt;a href="https://www.netlify.com/github-pages-vs-netlify/"&gt;netlify&lt;/a&gt;. I installed the &lt;a href="https://github.com/apps/netlify"&gt;Netlify app&lt;/a&gt; which automatically takes care of the building the repo &amp;amp; deploy previews so I didn't have to write any actions config.&lt;/p&gt;

&lt;p&gt;If you are interested to use GitHub pages for your library, you can use the &lt;a href="https://github.com/marketplace/actions/deploy-to-github-pages"&gt;Deploy to GitHub Pages&lt;/a&gt; action for this purpose.&lt;/p&gt;

&lt;p&gt;You can also try &lt;a href="https://cli.netlify.com/"&gt;Netlify CLI&lt;/a&gt; if you want to configure deploys with netlify through GitHub Actions.&lt;/p&gt;

&lt;p&gt;This build workflow is actively used in two of my libraries &lt;a href="https://github.com/react-native-toolkit/rex-state"&gt;rex-state&lt;/a&gt; &amp;amp; &lt;a href="https://github.com/react-native-toolkit/react-native-better-image"&gt;react-native-better-image&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/dani_akash_/automating-the-review-process-of-your-react-native-library-s-prs-4457"&gt;next blog&lt;/a&gt; post, I'll explain how to set up the review workflow!&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>actionshackathon</category>
      <category>github</category>
    </item>
    <item>
      <title>Rex State - a handy utility to convert your hooks into shared states</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Sat, 12 Sep 2020 13:14:47 +0000</pubDate>
      <link>https://forem.com/dani_akash_/rex-state-a-handy-utility-to-convert-your-hooks-into-shared-states-2f2h</link>
      <guid>https://forem.com/dani_akash_/rex-state-a-handy-utility-to-convert-your-hooks-into-shared-states-2f2h</guid>
      <description>&lt;h1&gt;
  
  
  Introducing &lt;a href="https://github.com/react-native-toolkit/rex-state"&gt;Rex State&lt;/a&gt; v1.0
&lt;/h1&gt;

&lt;p&gt;I initially built rex-state as a state management library, however, since it was using the Context API it wasn't very efficient with handling re-renders. &lt;/p&gt;

&lt;p&gt;But then its another feature became more prominent. It can easily convert any hook into a shared state!&lt;/p&gt;

&lt;p&gt;Focusing on this functionality, Today I'm releasing Rex State 1.0. This tool is easy to use and will work with your existing hooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Add rex-state to your project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add rex-state

&lt;span class="c"&gt;# or&lt;/span&gt;

npm i rex-state
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Consider you have the following counter hook ﹣&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;useCounterHook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialCount&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;increaseCount&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="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decreaseCount&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="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;increaseCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;decreaseCount&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can use rex-state to create a provider and a shared hook using the following code ﹣&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createRexStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rex-state&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;useStore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;useCounter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;RexProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CountProvider&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createRexStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;useCounterHook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Wrap your application inside the &lt;code&gt;CountProvider&lt;/code&gt; ﹣&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Starting off with an initial count of 10&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;CountProvider&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="mi"&gt;10&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;CountDisplay&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;Controls&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;CountProvider&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 you can use &lt;code&gt;useCounter&lt;/code&gt; hook inside both &lt;code&gt;&amp;lt;CountDisplay/&amp;gt;&lt;/code&gt; &amp;amp; &lt;code&gt;&amp;lt;Controls/&amp;gt;&lt;/code&gt; components. When the count changes in the &lt;code&gt;&amp;lt;Controls/&amp;gt;&lt;/code&gt; component, it will cause the &lt;code&gt;&amp;lt;CountProvider/&amp;gt;&lt;/code&gt; to re-render &amp;amp; will also update the &lt;code&gt;&amp;lt;CountDisplay/&amp;gt;&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;This is based on the React.Context API. I have written a detailed page on its &lt;a href="https://rex-state.netlify.app/?path=/story/intro-performance--page"&gt;performance&lt;/a&gt; &amp;amp; when to use it in your application.&lt;/p&gt;

&lt;p&gt;Following is a working codesandbox of the counter app ﹣&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/rex-counter-2m4zy?initialpath=/src/App.js"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Read about it detail on &lt;a href="https://github.com/react-native-toolkit/rex-state"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Share your thoughts about using this library. I'm open to feedbacks &amp;amp; ideas ✌🏽 &lt;/p&gt;

</description>
      <category>showdev</category>
      <category>react</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>A better Image component for React Native</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Sat, 05 Sep 2020 11:54:08 +0000</pubDate>
      <link>https://forem.com/dani_akash_/a-better-image-component-for-react-native-1bjb</link>
      <guid>https://forem.com/dani_akash_/a-better-image-component-for-react-native-1bjb</guid>
      <description>&lt;p&gt;Introducing a &lt;a href="https://github.com/react-native-toolkit/react-native-better-image" rel="noopener noreferrer"&gt;better image component&lt;/a&gt; for React Native!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Freact-native-toolkit%2Freact-native-better-image%2Fraw%2Fmaster%2Fassets%2Fcover.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Freact-native-toolkit%2Freact-native-better-image%2Fraw%2Fmaster%2Fassets%2Fcover.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React Native only includes a basic image component. However, I always needed two very important functionalities on the Image component:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;fallback image&lt;/strong&gt; if the original source fails to load&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progressive image loading&lt;/strong&gt; (especially for banners &amp;amp; cover images)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I customized the existing &lt;code&gt;&amp;lt;Image/&amp;gt;&lt;/code&gt; component and have been using this &lt;code&gt;&amp;lt;BetterImage/&amp;gt;&lt;/code&gt; component in my projects. Today, I'm open-sourcing my component to receive feedbacks &amp;amp; ideas from the community.&lt;/p&gt;

&lt;p&gt;Do try it out at &lt;a href="https://github.com/react-native-toolkit/react-native-better-image" rel="noopener noreferrer"&gt;react-native-toolkit/react-native-better-image&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/react-native-toolkit" rel="noopener noreferrer"&gt;
        react-native-toolkit
      &lt;/a&gt; / &lt;a href="https://github.com/react-native-toolkit/react-native-better-image" rel="noopener noreferrer"&gt;
        react-native-better-image
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A better image component for react-native with fallback images &amp;amp; progressive loading support
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/react-native-toolkit/react-native-better-image/raw/master/assets/logo.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Freact-native-toolkit%2Freact-native-better-image%2Fraw%2Fmaster%2Fassets%2Flogo.png" alt="better-image-logo" height="150px" width="150px"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;React Native Better Image&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A better image component for react-native with fallback images &amp;amp; progressive loading support&lt;/p&gt;
&lt;p&gt;Built on top of &lt;code&gt;View&lt;/code&gt;, &lt;code&gt;Image&lt;/code&gt; &amp;amp; &lt;code&gt;Animated&lt;/code&gt; components&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/react-native-toolkit/react-native-better-image/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/react-native-toolkit/react-native-better-image/workflows/build/badge.svg" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://codeclimate.com/github/react-native-toolkit/react-native-better-image/maintainability" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a4a341c9c3284f724ddbf22a65ce4be87a607084e9958d32fe4242c24a313651/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f61636635323433643133303534326464653763392f6d61696e7461696e6162696c697479" alt="Maintainability"&gt;&lt;/a&gt;
&lt;a href="https://codeclimate.com/github/react-native-toolkit/react-native-better-image/test_coverage" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2d4e00bf26fb70ccf2f9cfef2ee5dfb7f56ac6f4a4c85139f0b6d4ac72c7ae63/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f61636635323433643133303534326464653763392f746573745f636f766572616765" alt="Test Coverage"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/react-native-better-image" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/19a0060efe7e65d1f0ee0cf3a055632d0791eb6842ee26bec5b7880e0e0d836d/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f72656163742d6e61746976652d6265747465722d696d6167652e737667" alt="Version"&gt;&lt;/a&gt;
&lt;a href="http://www.npmtrends.com/react-native-better-image" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/35446872414b5bd2a1e42e1a3304bc0cde2ed1757ad364bead28ff31f9bb6a0f/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f72656163742d6e61746976652d6265747465722d696d6167652e737667" alt="Downloads"&gt;&lt;/a&gt;
&lt;a href="https://bundlephobia.com/result?p=react-native-better-image" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/adf17bceac94b98331dbb2411a0d1139e07e591a7ce209bdb0517e4681099ee1/68747470733a2f2f62616467656e2e6e65742f62756e646c6570686f6269612f6d696e7a69702f72656163742d6e61746976652d6265747465722d696d616765" alt="Bundlephobia"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/react-native-toolkit/react-native-better-image/stargazers" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d43cc5efef99fd1b125b486dd536993d0b2f2fbdd5b221c6f45a29ab964fd6ac/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f72656163742d6e61746976652d746f6f6c6b69742f72656163742d6e61746976652d6265747465722d696d6167652e7376673f7374796c653d736f6369616c" alt="Star on GitHub"&gt;&lt;/a&gt;
&lt;a href="https://github.com/react-native-toolkit/react-native-better-image/watchers" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b92d79aa12ee3ffd099af1f07dc1abf11075dd0c3b5d5ab61e86bd8470d8d351/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f77617463686572732f72656163742d6e61746976652d746f6f6c6b69742f72656163742d6e61746976652d6265747465722d696d6167652e7376673f7374796c653d736f6369616c" alt="Watch on GitHub"&gt;&lt;/a&gt;
&lt;a href="https://twitter.com/dani_akash_" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1f1fcba1f9f82591d3b4c6a2c8ecbf5d0f412bc9c5c969cb3552b5c924021b6b/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f64616e695f616b6173685f3f7374796c653d736f6369616c" alt="Twitter Follow"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/daniakash" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/88a6b4c69a94218bd565399cc2aad330c5933ad70c53064624cf8c25979c096f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d2545322539382539352545462542382538462532306275792532306d6525323061253230636f666665652d653835623436" alt="donate"&gt;&lt;/a&gt;
&lt;a href="https://www.buymeacoffee.com/daniakash/e/6983" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/73863f640623abeff79ec0f4c97b534d86df9aea671e5d323c0c4e04ff32f26f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d25463025394625384625383525323073706f6e736f722532307468697325323070726f6a6563742d653835623436" alt="sponsor"&gt;&lt;/a&gt;
&lt;a href="https://www.buymeacoffee.com/daniakash/e/7030" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0b314d0f3eec95a1e692a50e383583009ee9c148734a933c802eb687ba9aeba5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d476574253230537570706f72742d653835623436" alt="support"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://betterimage.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/56c844cdd2cb65db0b4eed09ce0fddfdb108db1d6345b0aa1a1851b7cbe9a1d0/68747470733a2f2f63646e2e6a7364656c6976722e6e65742f67682f73746f7279626f6f6b6a732f6272616e64406d61737465722f62616467652f62616467652d73746f7279626f6f6b2e737667" alt="Storybook"&gt;&lt;/a&gt; &lt;a href="https://chromatic.com/library?appId=5f5078c6fe7d0c0022c82f06&amp;amp;branch=master" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/35ff9f805414e152ea81d5e56b35cd1d5d56150ece20bfb6660f942c91f6be9a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d6368726f6d617469632d253233666335323166" alt="Chromatic"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/react-native-toolkit/react-native-better-image/raw/master/assets/cover.gif"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Freact-native-toolkit%2Freact-native-better-image%2Fraw%2Fmaster%2Fassets%2Fcover.gif" alt="better-image-cover"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Compatible with Expo &amp;amp; React Native Web 🚀&lt;/h3&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;PRs Welcome 👍✨&lt;/h3&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;📦 &lt;a href="https://github.com/react-native-toolkit/react-native-better-image#installation" rel="noopener noreferrer"&gt;Installation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ℹ️ &lt;a href="https://github.com/react-native-toolkit/react-native-better-image#usage" rel="noopener noreferrer"&gt;Usage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📃 &lt;a href="https://betterimage.netlify.app" rel="nofollow noopener noreferrer"&gt;Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;✨ &lt;a href="https://github.com/react-native-toolkit/react-native-better-image#motivation" rel="noopener noreferrer"&gt;Motivation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📱 &lt;a href="https://expo.io/@daniakash/react-native-better-image-example" rel="nofollow noopener noreferrer"&gt;Example App&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;yarn add react-native-better-image

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt;or&lt;/span&gt;

npm install react-native-better-image&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-v"&gt;BetterImage&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'react-native-better-image'&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;

&lt;span class="pl-c"&gt;// ...&lt;/span&gt;

&lt;span class="pl-c1"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;BetterImage&lt;/span&gt;
  &lt;span class="pl-c1"&gt;viewStyle&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;&lt;span class="pl-s1"&gt;style&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;
  &lt;span class="pl-c1"&gt;source&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-c1"&gt;uri&lt;/span&gt;: &lt;span class="pl-c"&gt;// image uri&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;
  &lt;span class="pl-c1"&gt;thumbnailSource&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-c1"&gt;uri&lt;/span&gt;: &lt;span class="pl-c"&gt;// thumbnail uri - will be displayed till image is loaded&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;
  &lt;span class="pl-c1"&gt;fallbackSource&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;
    &lt;span class="pl-c1"&gt;uri&lt;/span&gt;: &lt;span class="pl-c"&gt;// fallback image if original image fails to load&lt;/span&gt;
  &lt;span class="pl-kos"&gt;}&lt;/span&gt;&lt;span class="pl-kos"&gt;}&lt;/span&gt;
  &lt;span class="pl-c"&gt;// ...all other react-native image props&lt;/span&gt;
&lt;span class="pl-c1"&gt;/&lt;/span&gt;&lt;span class="pl-c1"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Motivation&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;React Native only includes a basic image component. I used to try solutions like &lt;a href="https://github.com/DylanVann/react-native-fast-image" rel="noopener noreferrer"&gt;react-native-fast-image&lt;/a&gt; but none actually worked for the…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/react-native-toolkit/react-native-better-image" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;I have also created a storybook with detailed docs at &lt;a href="https://betterimage.netlify.app/" rel="noopener noreferrer"&gt;betterimage.netlify.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What other features do you think are essential for the Image component? Share your ideas &amp;amp; I'll be happy to help 👍&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>reactnative</category>
      <category>expo</category>
      <category>react</category>
    </item>
    <item>
      <title>Drawing Triangles in React Native</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Fri, 05 Jun 2020 15:37:01 +0000</pubDate>
      <link>https://forem.com/dani_akash_/drawing-triangles-in-react-native-2akk</link>
      <guid>https://forem.com/dani_akash_/drawing-triangles-in-react-native-2akk</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--84QfNa3u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ekr53s3saeu00rwf0oiv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--84QfNa3u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ekr53s3saeu00rwf0oiv.png" alt="React Native Triangle"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--WT6pZeAT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1132493386995314688/Oh-ZyHQw_normal.jpg" alt="Dani Akash 🧪💥 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Dani Akash 🧪💥
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/dani_akash_"&gt;@dani_akash_&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      I have decided to focus on open-sourcing all the components I have built for React Native. Starting with the Triangle!&lt;br&gt;&lt;a href="https://t.co/F1ohUA9poE"&gt;github.com/react-native-t…&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      03:20 AM - 05 Jun 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1268744578305110019" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1268744578305110019" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1268744578305110019" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      7
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;I always come across a scenario where my UI needs a triangle view. Also I needed fine control over all aspects of the triangle view. Hence I built &lt;a href="https://github.com/react-native-toolkit/triangle"&gt;@react-native-toolkit/triangle&lt;/a&gt; view based on the well known CSS trick to create triangles on the web.&lt;/p&gt;

&lt;p&gt;As my requirements grew, I was adding more features to the library and now it supports almost all possible triangles you need. Hence I'm open sourcing it today for general use.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/triangle-m0z2l"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I initially used &lt;a href="https://www.npmjs.com/package/react-native-triangle"&gt;react-native-triangle&lt;/a&gt; but it's configuration is fairly limited and I couldn't control many of the triangle properties. Hence this library became a necessity.&lt;/p&gt;

&lt;p&gt;Also, I have started to work on open sourcing all the libraries I built for react native over the years for my personal projects. Will be slowly moving them over to &lt;a href="https://github.com/react-native-toolkit"&gt;React Native Toolkit&lt;/a&gt;. Stay tuned for future updates!&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I recreated React's class component lifecycle methods with hooks</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Fri, 22 May 2020 01:54:09 +0000</pubDate>
      <link>https://forem.com/dani_akash_/i-recreated-react-s-class-component-lifecycle-methods-with-hooks-2bm3</link>
      <guid>https://forem.com/dani_akash_/i-recreated-react-s-class-component-lifecycle-methods-with-hooks-2bm3</guid>
      <description>&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VDM_WY2d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/EYg-GWwVcAAsETO.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--WT6pZeAT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1132493386995314688/Oh-ZyHQw_normal.jpg" alt="Dani Akash 🧪💥 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Dani Akash 🧪💥
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/dani_akash_"&gt;@dani_akash_&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--52oNvK_0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-ff4bdab814039c4cb172a35ea369e0ea9c6a4b59b631a293896ae195fa26a99d.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      felt evil, so created this 😈 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      04:37 AM - 21 May 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1263327984640946177" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1263327984640946177" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      2
      &lt;a href="https://twitter.com/intent/like?tweet_id=1263327984640946177" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      8
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
 

&lt;p&gt;Project - &lt;a href="https://github.com/DaniAkash/lifecycle-hooks"&gt;lifecycle-hooks&lt;/a&gt;, also available in &lt;a href="https://www.npmjs.com/package/@daniakash/lifecycle-hooks"&gt;npm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recently started working on an old react native project where I had to upgrade &lt;strong&gt;react-navigation&lt;/strong&gt; from v3 to v5. &lt;/p&gt;

&lt;p&gt;To take advantage of the new &lt;strong&gt;navigation hooks&lt;/strong&gt; in version 5, I had to migrate existing class components to react hooks.&lt;/p&gt;

&lt;p&gt;At first, it seemed like a straight forward case of refactoring some bit of code. However, I quickly realized how difficult the task at hand is...&lt;/p&gt;

&lt;p&gt;Class component to hooks conversion is just not straight forward. Hooks are &lt;em&gt;awesome when you are building new components&lt;/em&gt; but they are definitely not created with migrating class components in mind.&lt;/p&gt;

&lt;p&gt;As &lt;a href="https://reactjs.org/docs/hooks-intro.html#no-breaking-changes"&gt;react documentation&lt;/a&gt; says, class components aren't going away, so you probably won't have to migrate your project to functional components in most cases.&lt;/p&gt;

&lt;p&gt;But if you run into a situation like me where you need the powerful hooks from &lt;em&gt;react-navigation&lt;/em&gt;, &lt;em&gt;react-spring&lt;/em&gt; or any other similar library, &lt;a href="https://github.com/DaniAkash/lifecycle-hooks"&gt;lifecycle-hooks&lt;/a&gt; will make your migration a lot easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  traditional class state
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Initialization&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&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="na"&gt;email&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="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// updating name&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  lifecycle-hook's &lt;code&gt;useState&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@daniakash/lifecycle-hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;// Initialization&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&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="na"&gt;email&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="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// updating name&lt;/span&gt;
&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Likewise, I have also created hooks for &lt;code&gt;componentDidMount&lt;/code&gt;, &lt;code&gt;componentDidUpdate&lt;/code&gt; &amp;amp; &lt;code&gt;componentWillUnmount&lt;/code&gt; which will let you quickly move code without having to worry about dependency arrays of &lt;code&gt;useEffect&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can try these hooks in the following codesandbox playground. Let me know your thoughts! Feedbacks &amp;amp; PRs welcome ✨&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/lifecycle-hooks-playground-n6qes"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;

</description>
      <category>showdev</category>
      <category>react</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>UX friendly loading indicators</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Thu, 09 Apr 2020 18:36:06 +0000</pubDate>
      <link>https://forem.com/dani_akash_/ux-friendly-loading-indicators-3obd</link>
      <guid>https://forem.com/dani_akash_/ux-friendly-loading-indicators-3obd</guid>
      <description>&lt;p&gt;I love loading indicators. Especially ever since &lt;a href="https://lottiefiles.com/" rel="noopener noreferrer"&gt;lottie animations&lt;/a&gt; came out, I have been playing around with different kinds of animations as loading indicators. However, these loading indicators often pose a huge UX Issue when used to display "waiting" for fetch requests.&lt;/p&gt;

&lt;p&gt;Let's say you have a nice loading indicator like &lt;a href="https://lottiefiles.com/18706-loading-icon" rel="noopener noreferrer"&gt;this one&lt;/a&gt; &amp;amp; a webpage that makes a network request to fetch quote of the day. &lt;/p&gt;

&lt;p&gt;If you use this loading indicator directly, on a super-fast connection, where the request resolves in 200ms, then you'll notice that the loading indicator basically flashes in between the old &amp;amp; new content ﹣ &lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/regular-loading-jgu83"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The loading indicator is nice for content that takes 1000ms+ response time. However, it is not suitable for content that takes very small time like 200ms. But the content, however, is loaded over the network which means for users with fast 5G 🛰 connection the response time is going to be 200ms 🚀 while for users with slow 3G/2G connections the response time might be higher for the same content ☹️&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;p&gt;To provide optimal user experience in this scenario, we need different loading indicators for each type of network speeds and we have to maintain a separate &lt;strong&gt;"loading-state"&lt;/strong&gt; that ensures we are displaying the proper loading indicator.&lt;/p&gt;

&lt;p&gt;On digging deep into this topic, React team has done a great deal of research in the &lt;a href="https://reactjs.org/docs/concurrent-mode-suspense.html" rel="noopener noreferrer"&gt;suspense&lt;/a&gt; module which does optimistic rendering and doesn't display any loading indicators if the request is resolved quickly!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I have written a summary of my learnings in a separate &lt;a href="https://twitter.com/dani_akash_/status/1247617443897290752" rel="noopener noreferrer"&gt;tweet thread&lt;/a&gt; which you can also read using &lt;a href="https://threadreaderapp.com/thread/1247617443897290752.html" rel="noopener noreferrer"&gt;thread reader&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For an ideal UX for a scenario such as the one in the above codesandbox sample, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if the request resolves in 200ms 

&lt;ul&gt;
&lt;li&gt;no loading indicator is needed&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;if the request resolves in 500ms

&lt;ul&gt;
&lt;li&gt;no loading indicator is needed till 200ms&lt;/li&gt;
&lt;li&gt;a loading indicator appears at 300ms (something non-intrusive)&lt;/li&gt;
&lt;li&gt;the loading indicator is visible till 600ms (even though the data is retrieved at 500ms) to ensure the UI doesn't appear as if it is stuttering/flashing for the user&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;if the request resolves in 1200ms

&lt;ul&gt;
&lt;li&gt;following above timeline, a loading indicator is displayed till 600ms&lt;/li&gt;
&lt;li&gt;after 1000ms, another loading indicator appears (seems like the user is in a slow network region)&lt;/li&gt;
&lt;li&gt;this loading indicator will remain visible till 1300ms (to prevent the users from seeing a flashing screen)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Applying this logic, try the following example ﹣&lt;br&gt;
&lt;iframe src="https://codesandbox.io/embed/loading-state-b8o5z"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This time, at &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;200ms no loading indicators are needed.&lt;/li&gt;
&lt;li&gt;300ms+ we have a loading indicator which a gentle opacity that is mandatorily visible for 300ms before displaying the data&lt;/li&gt;
&lt;li&gt;1000ms+ we have another animated loading indicator which is also visible for 300ms before displaying the data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the second example, I have built a javascript library ﹣ &lt;a href="https://github.com/DaniAkash/loading-state" rel="noopener noreferrer"&gt;&lt;strong&gt;"loading-state"&lt;/strong&gt;&lt;/a&gt; which maintains the loading state internally using &lt;code&gt;setTimeout&lt;/code&gt; and provides an easy to use API to display the loading indicators.&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;import&lt;/span&gt; &lt;span class="nx"&gt;loader&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loading-state&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cool!&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="na"&gt;shortLoading&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;{},&lt;/span&gt; &lt;span class="c1"&gt;// callback to display first loading indicator&lt;/span&gt;
    &lt;span class="na"&gt;longLoading&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;{},&lt;/span&gt; &lt;span class="c1"&gt;// callback to display the second indicator&lt;/span&gt;
    &lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="c1"&gt;// success callback with the result of the promise&lt;/span&gt;
    &lt;span class="na"&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;// error callback with the thrown error&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;busyDelayMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// how long to wait till displaying first indicator&lt;/span&gt;
    &lt;span class="na"&gt;longBusyDelayMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// how long to wait till displaying second indicator&lt;/span&gt;
    &lt;span class="na"&gt;shortIndicatorVisibilityMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// how long to display first indicator&lt;/span&gt;
    &lt;span class="na"&gt;longIndicatorVisibilityMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// how long to display second indicator&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;With this, we can effectively maintain the loading state of our network request &amp;amp; ensure that the UX is not affected for the user based on their network speeds!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ux</category>
      <category>showdev</category>
    </item>
    <item>
      <title>React Native Responsive Dimensions - Updated with more responsiveness for foldable devices</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Sat, 21 Mar 2020 13:11:18 +0000</pubDate>
      <link>https://forem.com/dani_akash_/react-native-responsive-dimensions-updated-with-more-responsiveness-for-foldable-devices-1a5d</link>
      <guid>https://forem.com/dani_akash_/react-native-responsive-dimensions-updated-with-more-responsiveness-for-foldable-devices-1a5d</guid>
      <description>&lt;p&gt;React Native Responsive Dimensions have been updated to version 3.1.0 with full typescript support &amp;amp; a whole bunch of new utilities quickly check out the new release at &lt;a href="https://github.com/DaniAkash/react-native-responsive-dimensions"&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First published three years ago as a simple utility to resize some views based on the device's screen size, responsive dimensions quickly became one of the favourite tools for my colleagues and many react native developers. I was updating it once a year with a few new things like the &lt;a href="https://github.com/DaniAkash/react-native-responsive-dimensions/releases/tag/3.0.0"&gt;responsive hooks&lt;/a&gt; last year. But this update is quite important!&lt;/p&gt;

&lt;p&gt;I recently worked with &lt;a href="https://dev.to/rachelnabors"&gt;Rachel Nabors&lt;/a&gt; on React Native &lt;a href="https://github.com/facebook/react-native-website/issues/1579"&gt;Component Docs Drive&lt;/a&gt; where while documenting the actual react native's inbuilt &lt;a href="https://github.com/facebook/react-native-website/pull/1671"&gt;dimensions&lt;/a&gt; module, I realized Responsive Dimensions has a great potential to simplify application development for foldables and react-native-web apps.&lt;/p&gt;

&lt;p&gt;With this new update, Responsive Dimensions now have&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separate utilities for Responsive "window" &amp;amp; "screen" sizes (screen sizes will be useful while working with foldables)&lt;/li&gt;
&lt;li&gt;New responsive screen size hooks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useDimensionsChange&lt;/code&gt; hook to let your application respond to dimension changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See the &lt;a href="https://github.com/DaniAkash/react-native-responsive-dimensions/releases/tag/3.1.0"&gt;release notes&lt;/a&gt; for a full list of changes and also checkout the example projects at &lt;a href="https://snack.expo.io/@daniakash/responsive-dimensions"&gt;Snack&lt;/a&gt; &amp;amp; &lt;a href="https://codesandbox.io/s/react-native-responsive-dimensions-hooks-2cqm8"&gt;CodeSandbox&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do let me know if you have any feature requests or feedbacks ﹣ always happy to help 😁👍&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>showdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Introducing Rex State 🦖</title>
      <dc:creator>Dani Akash 🧪💥</dc:creator>
      <pubDate>Thu, 19 Mar 2020 00:55:27 +0000</pubDate>
      <link>https://forem.com/dani_akash_/introducing-rex-state-5gg9</link>
      <guid>https://forem.com/dani_akash_/introducing-rex-state-5gg9</guid>
      <description>&lt;p&gt;&lt;em&gt;The simplest way to manage your React States! Check out &lt;a href="https://codesandbox.io/s/state-management-with-rex-state-4ivcd"&gt;the demo app&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I have been using Redux and Mobx for managing states in my react projects. Ever since React Hooks were introduced I had been playing around with the Context API experimenting different ways to manage states.&lt;/p&gt;

&lt;p&gt;I finally came up with &lt;strong&gt;Rex State&lt;/strong&gt;, a tool that I have been using in my personal projects for creating re-usable hooks as well as state management.&lt;/p&gt;

&lt;p&gt;The idea behind Rex State is making your states more declarative and providing an easy to use API to connect with the React Components. A classic example ﹣&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useRex&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rex-state&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;useInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRex&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="dl"&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="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;value&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;updateValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;InputField&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useInput&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="nt"&gt;input&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&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;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Add Text here..."&lt;/span&gt;
      &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;updateValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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



&lt;p&gt;Rex State can also be used as a state management tool. A 400 bytes replacement to redux or mobx ✨ &lt;/p&gt;

&lt;p&gt;Follow this &lt;a href="https://github.com/DaniAkash/rex-state#tutorial"&gt;tutorial&lt;/a&gt; to see how to manage states with Rex State.&lt;/p&gt;

&lt;p&gt;Feedbacks &amp;amp; PRs welcome! 😁&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/DaniAkash/rex-state"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>discuss</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
