<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Wen Long</title>
    <description>The latest articles on DEV Community by Wen Long (@wenlong12345).</description>
    <link>https://dev.to/wenlong12345</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%2F591576%2F0e5b056e-499c-4391-b915-def8c700dec3.jpeg</url>
      <title>DEV Community: Wen Long</title>
      <link>https://dev.to/wenlong12345</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wenlong12345"/>
    <language>en</language>
    <item>
      <title>Beautiful Portfolio Website with NextJS &amp; ChakraUI</title>
      <dc:creator>Wen Long</dc:creator>
      <pubDate>Tue, 04 Jan 2022 02:28:05 +0000</pubDate>
      <link>https://dev.to/wenlong12345/beautiful-portfolio-website-with-nextjs-chakraui-428c</link>
      <guid>https://dev.to/wenlong12345/beautiful-portfolio-website-with-nextjs-chakraui-428c</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cOLvymuG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2r8bduq58c5f0v3urlk8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cOLvymuG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2r8bduq58c5f0v3urlk8.png" alt="Image description" width="880" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Website: &lt;a href="https://teo-nextjs-portfolio.vercel.app/"&gt;https://teo-nextjs-portfolio.vercel.app/&lt;/a&gt;&lt;br&gt;
Github: &lt;a href="https://github.com/WenLonG12345/teo-nextjs-portfolio"&gt;https://github.com/WenLonG12345/teo-nextjs-portfolio&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/qHkA8ruGz-g"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TLd8lyXV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://img.youtube.com/vi/qHkA8ruGz-g/maxresdefault.jpg" alt="Watch the video" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After more than 2 months working in React Native, I was roughly understand how React works. Then, an idea came to my mind, why don’t I build myself a personal portfolio? It was a great thing to built to showcase all my skills and even good for presenting myself.&lt;br&gt;
But mobile apps seems a bit burden as not everyone willing to download and install the apps into their phone just to understand your work right? People usually just want a click to reach their destination. Hence, website is my 1st choice!&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;NextJS — popular React framework that offers many benefits without complex configuration.&lt;/li&gt;
&lt;li&gt;ChakraUI — beautiful and simple UI components library&lt;/li&gt;
&lt;li&gt;framer-motion — easy-to-use animation library for React&lt;/li&gt;
&lt;li&gt;Spotify Now Playing integration&lt;/li&gt;
&lt;li&gt;EmailJS — email service that send email directly with custom template.
Vercel — platform used for deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Showcase (Dark Mode)
&lt;/h2&gt;

&lt;p&gt;Here is some of the screenshot for the features.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YLv5ODwy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qn06gil6u3hwwd8afh0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YLv5ODwy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qn06gil6u3hwwd8afh0e.png" alt="Image description" width="880" height="685"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PjpDM0Es--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zt395k1q2onjywc2dtok.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PjpDM0Es--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zt395k1q2onjywc2dtok.png" alt="Image description" width="880" height="608"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nCDouDya--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/arn6qg559hqhga39v1bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nCDouDya--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/arn6qg559hqhga39v1bg.png" alt="Image description" width="880" height="613"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--83cTHrY9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cv2u46lbgqq9k92b3f71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--83cTHrY9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cv2u46lbgqq9k92b3f71.png" alt="Image description" width="880" height="597"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MOcKmbSf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/79maxpv27j44pbfyl563.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MOcKmbSf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/79maxpv27j44pbfyl563.png" alt="Image description" width="880" height="639"&gt;&lt;/a&gt;&lt;br&gt;
Of course, with Chakra UI, it is very easy to setup both light &amp;amp; dark mode by using useColorModeValue(). (personally prefer dark mode).&lt;/p&gt;

&lt;h2&gt;
  
  
  Screenshot (Light Mode)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AQGV1Uwa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ch3yh6a7c3dmqiguzoyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AQGV1Uwa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ch3yh6a7c3dmqiguzoyn.png" alt="Image description" width="880" height="497"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rmMgLrFP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p8h92igiu80nkfiqr3e3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rmMgLrFP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p8h92igiu80nkfiqr3e3.png" alt="Image description" width="880" height="674"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CXdseMD3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fu18jx3zl140w66zdquf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CXdseMD3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fu18jx3zl140w66zdquf.png" alt="Image description" width="880" height="620"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--44sPBgLv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0nitjcwnj61yekc925n9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--44sPBgLv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0nitjcwnj61yekc925n9.png" alt="Image description" width="880" height="691"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WEfLUTfw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9wshj4o7up4h451pcyji.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WEfLUTfw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9wshj4o7up4h451pcyji.png" alt="Image description" width="880" height="600"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VsqhvQ7D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ioibu2tpwxqo97iogp5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VsqhvQ7D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ioibu2tpwxqo97iogp5.png" alt="Image description" width="880" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mobile-responsive
&lt;/h2&gt;

&lt;p&gt;Also, I tried hard to cater all the screens to be mobile-responsive. Here is some screenshots to show.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lVs8Myrb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a63jon28lvbrhjuxvzh8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lVs8Myrb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a63jon28lvbrhjuxvzh8.png" alt="Image description" width="880" height="507"&gt;&lt;/a&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aHsA-OvY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2po55y120xn7zx2gskl0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aHsA-OvY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2po55y120xn7zx2gskl0.png" alt="Image description" width="880" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It is my 1st time working on web development. My experience was amazing with all these beautiful UI and animation. The challenges I faced was screen size responsive. I work on many different solutions and eventually obtain the best value for each components.&lt;br&gt;
Do give me any feedback if I made any mistakes in this project. But overall, I think it is a good practices for me as a developer and programmer to keep myself passionate on develop something for either myself or the community.&lt;br&gt;
Thanks for your time in reading this. and let’s meet in the next article! 🧀&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>chakraui</category>
      <category>react</category>
      <category>framermotion</category>
    </item>
    <item>
      <title>React Native - Beautiful Horoscope App</title>
      <dc:creator>Wen Long</dc:creator>
      <pubDate>Sun, 02 Jan 2022 11:04:16 +0000</pubDate>
      <link>https://dev.to/wenlong12345/react-native-beautiful-horoscope-app-341n</link>
      <guid>https://dev.to/wenlong12345/react-native-beautiful-horoscope-app-341n</guid>
      <description>&lt;p&gt;Recently I was working on sample project that helps to sharpen my skill in React Native (RN), and I found an interesting API which related to horoscope. It was &lt;a href="https://github.com/sameerkumar18/aztro"&gt;Aztro&lt;/a&gt; API, an open-source horoscope API. Hence, I decided to write myself a Horoscope App!&lt;/p&gt;

&lt;h2&gt;
  
  
  Screenshot of Horoscope App
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zWIjg1sj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2APOgx2ZnJ4a-BMgcKK9HJMA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zWIjg1sj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2APOgx2ZnJ4a-BMgcKK9HJMA.jpeg" alt="Screenshot from IPhone 13" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech-stack
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;React Native (of-course!) and React Hooks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redux &amp;amp; Redux-Saga&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Axios&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because of my company projects are using Redux and Redux-Saga, and I am still very weak on the concept, hence I decided to make the app with Redux and Redux-Saga as the app’s state management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Redux &amp;amp; Redux Saga
&lt;/h2&gt;

&lt;p&gt;Redux is one of the most popular state management framework for React application and Redux Saga helps to manage the side effect asynchronously. You may learn more on &lt;a href="https://redux.js.org/"&gt;Redux&lt;/a&gt; and &lt;a href="https://redux-saga.js.org/"&gt;Redux Saga&lt;/a&gt;. (I am still beginner on these! 😃). Their explanation are pretty clear but real-life experience is always better than reading book!&lt;/p&gt;

&lt;p&gt;Back to API, It was a POST request with 2 params, sign and day .&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST: https://aztro.sameerkumar.website?sign= &amp;lt;sign&amp;gt; &amp;amp;day= &amp;lt;day&amp;gt;

&amp;lt;!-- RESPONSE --&amp;gt; 
{"current_date": "November 1, 2021", "compatibility": " Cancer", "lucky_time": " 7am",
 "lucky_number": " 64", "color": " Spring Green", "date_range": "Mar 21 - Apr 20",
 "mood": " Relaxed", "description": "It's finally time for you to think about just
  one thing: what makes you happy. "}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here is the axios POST request implementation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7QhsjneR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2216/1%2Am30F7VMDZh_fOB5J1AE4hA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7QhsjneR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2216/1%2Am30F7VMDZh_fOB5J1AE4hA.png" alt="code" width="880" height="747"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it! Simple API call right? but how can we integrate it into Redux?&lt;/p&gt;

&lt;p&gt;There are &lt;strong&gt;3 important parts: Actions, Reducers &amp;amp; Store&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Actions&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zb4hj5ZB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ADSGzWF-2TpVJgPQN_sqsFw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zb4hj5ZB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ADSGzWF-2TpVJgPQN_sqsFw.png" alt="code1" width="880" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the API requested, there will 2 be request params sign &amp;amp; day and we created a type for it, API_REQUEST&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Reducers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mnWW922V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2360/1%2ADx20vMDv6sjqZcQ8VcJKYw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mnWW922V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2360/1%2ADx20vMDv6sjqZcQ8VcJKYw.png" alt="code" width="880" height="1265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, we defined our initial state where it contains loading , error &amp;amp; data . Then, we created a HoroscopeReducer that take current state, perform an action and return it with a new state. In the snippets, when we requesting from API, loading is set to true. If successfully get response, loading is set to false and data is set to response’s data. Meanwhile if error happens, error will be set to response’s error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Store&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Store is the place where hold the applicate state. Since horoscopeRequest is an async function, we can use Redux Saga to handle these operation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gjb20-A3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2332/1%2ACYs1TWMVzSoPyocM1a5zVg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gjb20-A3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2332/1%2ACYs1TWMVzSoPyocM1a5zVg.png" alt="code2" width="880" height="791"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We created a Saga watcher in generator function getHoroscope based on API_REQUEST actions and takeLatest will only take care of the latest sagas and automatically cancel any previous on-going sagas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xse7810i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AvRwyRV8vzGnoN3XzJQiqAQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xse7810i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AvRwyRV8vzGnoN3XzJQiqAQ.png" alt="code3" width="880" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I had created a rootSaga in case there is any further sagas that can be merge into a single entry point for sagaMiddleware to run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sr2CHNUs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2160/1%2AgORNNY-7zmMcdoJiAI8e7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sr2CHNUs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2160/1%2AgORNNY-7zmMcdoJiAI8e7w.png" alt="code4" width="880" height="737"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, we create store with sagaMiddleware. Then run our rootSaga and render our application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Render Application
&lt;/h2&gt;

&lt;p&gt;After having store, we need a provider to bind our store to our application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---RLr6mgp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2188/1%2ApUiON_Ar6M3GLKSjqG4wEA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---RLr6mgp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2188/1%2ApUiON_Ar6M3GLKSjqG4wEA.png" alt="code5" width="880" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are almost there! But how can we call our API in UI?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZX1Nma2V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2884/1%2AhEzTdFMJkZfJBIR9vllb8A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZX1Nma2V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2884/1%2AhEzTdFMJkZfJBIR9vllb8A.png" alt="code6" width="880" height="771"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since we only need to request API when selected a horoscope, we will request it in useEffect() (when it first launched the page &amp;amp; changing date). dispatch is used for request API.&lt;/p&gt;

&lt;p&gt;Then, mapStateToProps is needed to map our state’s data into props, and connect mapStateToProps to our HoroscopeDetail .&lt;/p&gt;

&lt;p&gt;Finally, we can get our state in HoroscopeDetail ‘s props — horoscopeModel !&lt;/p&gt;

&lt;h2&gt;
  
  
  UIUX design
&lt;/h2&gt;

&lt;p&gt;There is 2 page in this application, which is Home &amp;amp; HoroscopeDetail .&lt;/p&gt;

&lt;p&gt;In Home , I had created a FlatList to render horoscopeList (array of 12 zodiac) with customised HoroscopeCard .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WYt9xJsb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3000/1%2ArolfPVQSP_0A-gJ2dl_M3Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WYt9xJsb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3000/1%2ArolfPVQSP_0A-gJ2dl_M3Q.png" alt="code" width="880" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ddnvTbPE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ACnQYebTC2oZnAOVPC-H_Mg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ddnvTbPE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ACnQYebTC2oZnAOVPC-H_Mg.png" alt="HoroscopeCard Preview" width="276" height="346"&gt;&lt;/a&gt;&lt;em&gt;HoroscopeCard Preview&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In HoroscopeDetail , all the components are wrapped into SafeAreaView and ScrollView . Figure below shows the overall of the components used.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fz1hGlSl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AhhuAvEqCGO-fZAQ5HZWCEA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fz1hGlSl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AhhuAvEqCGO-fZAQ5HZWCEA.png" alt="code" width="556" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c2NZjh19--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3344/1%2AkTZl-sLkJhdFtwCUWZl7Dg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c2NZjh19--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3344/1%2AkTZl-sLkJhdFtwCUWZl7Dg.png" alt="code" width="880" height="1025"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;iOS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oNgZNraB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Az8oRGOEUNKA1aZbsTuT4KA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oNgZNraB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Az8oRGOEUNKA1aZbsTuT4KA.gif" alt="iospreview" width="324" height="692"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Android&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MtGlhp6W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AiEVsrrUa-sBhfvvDuF1nZw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MtGlhp6W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AiEVsrrUa-sBhfvvDuF1nZw.gif" alt="androidpreview" width="288" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;That’s all from me! Hope your guys enjoy reading my article and love what I had done. However, there is still some features to be enhance.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Shared element transition for zodiac icon.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Feature to share horoscope to your friends.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AppWidgets to show today’s horoscope.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And plenty more..&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I had built a testing Android APK for you guys to download and try it out (check my Github link on bottom of the article)! Do drop me any feedback and please correct me if I have done anything wrong in this project. Happy React-Native-ing! 🍷&lt;/p&gt;

&lt;p&gt;Github: &lt;a href="https://github.com/WenLonG12345/RNHoroscope"&gt;https://github.com/WenLonG12345/RNHoroscope&lt;/a&gt;&lt;/p&gt;

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