Async actions with Redux Thunk middleware in React Native apps
Tags: reactnative, redux, middleware
Published: 2020-03-28 14:35:39

<main role="main"><article class=" u-minHeight100vhOffset65 u-overflowHidden postArticle postArticle--full is-supplementalPostContentLoaded is-withAccentColors" lang="en"><div class="postArticle-content js-postField js-notesSource editable" id="editor_6" g_editable="true" role="textbox" contenteditable="true" data-default-value="Title
Tell your story…" spellcheck="false"><section name="950a" class="section section--body section--first section--last"><div class="section-divider"><hr class="section-divider"></div><div class="section-content"><div class="section-inner sectionLayout--insetColumn"><p name="abae" class="graf graf--p graf-after--figure">This post will assist any developer to learn on how to implement async actions with the help of middleware (redux-thunk) in react native apps. We’ll approach the implementation by creating a simple application.</p><blockquote name="f4dc" class="graf graf--blockquote graf-after--p"><em class="markup--em markup--blockquote-em">Complete source code of this tutorial is available in the </em><a href="https://github.com/enappd/react-native-redux-thunk.git"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank">React-native-redux-thunk-example</a></blockquote><h3 name="c757" class="graf graf--h3 graf-after--blockquote">What Is React&nbsp;Native?</h3><figure tabindex="0" contenteditable="false" name="d944" class="graf graf--figure graf-after--h3"><div class="aspectRatioPlaceholder is-locked" style="max-width: 200px; max-height: 200px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 100%;"></div><img class="graf-image" data-image-id="1*hVemiPgn143L4vIdAevNvw.jpeg" data-width="200" data-height="200" src="https://cdn-images-1.medium.com/max/800/1*hVemiPgn143L4vIdAevNvw.jpeg"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">React Native&nbsp;logo</figcaption></figure><p name="05ce" class="graf graf--p graf-after--figure is-selected">React Native is a JavaScript framework for writing real, natively rendering mobile applications for iOS and Android. It’s based on React, Facebook’s JavaScript library for building user interfaces, but instead of targeting the browser, it targets mobile platforms. In other words: web developers can now write mobile applications that look and feel truly “native,” all from the comfort of a JavaScript library that we already know and love. Plus, because most of the code you write can be shared between platforms, React Native makes it easy to simultaneously develop for both Android and iOS.</p><p name="7fee" class="graf graf--p graf-after--p">Similar to React for the Web, React Native applications are written using a mixture of JavaScript and XML markup, known as JSX. Then, under the hood, the React Native “bridge” invokes the native rendering APIs in Objective-C (for iOS) or Java (for Android). Thus, your application will render using real mobile UI components, not webviews, and will look and feel like any other mobile application. React Native also exposes JavaScript interfaces for platform APIs, so your React Native apps can access platform features like the phone camera, or the user’s location.</p><p name="9d66" class="graf graf--p graf-after--p">React Native currently supports both iOS and Android and has the potential to expand to future platforms as well. In this blog, we’ll cover both iOS and Android. The vast majority of the code we write will be cross-platform. And yes: you can really use React Native to build production-ready mobile applications! Some example: <a href="http://bit.ly/1YipO7A"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Facebook</a>, <a href="http://bit.ly/1PPEiZH"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Palantir</a>, and <a href="http://bit.ly/1PPEjNg"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">TaskRabbit</a> are already using it in production for user-facing applications.</p><h3 name="718d" class="graf graf--h3 graf-after--p">What is&nbsp;Redux?</h3><p name="bfce" class="graf graf--p graf-after--h3"><a href="https://redux.js.org/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--p-strong">Redux</strong></a> is a standalone state management library, which can be used with any library or framework. If your background is <strong class="markup--strong markup--p-strong">React developer</strong>, then you have used the <strong class="markup--strong markup--p-strong">Redux library with React</strong>. The primary use of <strong class="markup--strong markup--p-strong">Redux</strong> is that we can use one application state as a global state and interact with the state from any react component is very easy whether they are siblings or parent-child.</p><figure tabindex="0" contenteditable="false" name="d2c9" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 200px; max-height: 181px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 90.5%;"></div><img class="graf-image" data-image-id="1*kwMieaTmikxMDhZfI-yeaw.png" data-width="200" data-height="181" src="https://cdn-images-1.medium.com/max/800/1*kwMieaTmikxMDhZfI-yeaw.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Redux Logo</figcaption></figure><blockquote name="ba58" class="graf graf--blockquote graf-after--figure"><strong class="markup--strong markup--blockquote-strong">Basic usage of Redux comes into picture when the app gets large and complex. In such apps, simple data management as parent-child becomes difficult using </strong><code class="markup--code markup--blockquote-code"><strong class="markup--strong markup--blockquote-strong"><em class="markup--em markup--blockquote-em">props</em></strong></code><strong class="markup--strong markup--blockquote-strong">. There are multiple components trying to communicate with multiple other components. In such cases, Redux comes in handy.</strong></blockquote><p name="ada6" class="graf graf--p graf-after--blockquote">Redux can be broken down into few sections while building the application which is listed below.</p><p name="c1ca" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Actions: “</strong>are payloads of information that send data from your application to your store. They are the <em class="markup--em markup--p-em">only</em> source of information for the store.” this means if any state change necessary the change required will be dispatched through the actions.</p><p name="77ce" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Reducers: “</strong>Actions<strong class="markup--strong markup--p-strong"> </strong>describe the fact that <em class="markup--em markup--p-em">something happened</em>, but don’t specify how the application’s state changes in response. This is the job of reducers.” when an action is dispatched for state change its the reducers duty to make the necessary changes to the state and return the new state of the application.</p><p name="090f" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Store: </strong>with help of reducers a store can be created which holds the entire state of the application it is recommended to use a single store for the entire application than having multiple stores which will violate the use of redux which only has a single store.</p><p name="bb72" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Components (UI): </strong>This<strong class="markup--strong markup--p-strong"> </strong>is where the UI of the application is kept.</p><p name="4062" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Middlewares</strong>: Redux allows us to put a middleware that sits between an action being dispatched and the <strong class="markup--strong markup--p-strong">action</strong> that reaches to the <strong class="markup--strong markup--p-strong">reducers</strong>. Two very popular middleware libraries that will allow for side effects and asynchronous activities are <a href="https://github.com/reduxjs/redux-thunk"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Redux Thunk</a> and <a href="https://github.com/redux-saga/redux-saga"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Redux Saga</a>. We’ll learn more about thunk here.</p><p name="8450" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Redux Thunk</strong> is the middleware that lets you call the action creators that return a function instead of the action object. That function then receives the store’s dispatch method, which is then used to dispatch the regular synchronous actions inside a body of the function once the asynchronous operations have completed. The <strong class="markup--strong markup--p-strong">thunk</strong> is a concept in programming where a function is used to delay the evaluation/calculation of an operation. I know it’s too much of jargon, so let’s see how it works in the app.</p><figure tabindex="0" contenteditable="false" name="5625" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 541px; max-height: 295px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 54.50000000000001%;"></div><img class="graf-image" data-image-id="1*2--d_JqkSBPUBIe_TsppPA.jpeg" data-width="541" data-height="295" src="https://cdn-images-1.medium.com/max/800/1*2--d_JqkSBPUBIe_TsppPA.jpeg"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Redux workflow in a simple schematic</figcaption></figure><h3 name="ea15" class="graf graf--h3 graf-after--figure">Steps for Implementing R<code class="markup--code markup--h3-code">edux-thunk</code> in React Native&nbsp;app</h3><p name="0569" class="graf graf--p graf-after--h3">We will follow these step-by-step instructions to create our React Native with Redux Thunk</p><p name="d58c" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 1: Create a Basic React Native app</strong></p><p name="dce7" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 2: Running app on a device</strong></p><p name="4a6a" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 3: Install the necessary packages to connect your app with redux.</strong></p><p name="f9d3" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 4: Create the necessary folders inside Root.</strong></p><p name="7e88" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 5: Create Actions.</strong></p><p name="4e22" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 6:- Create rootReducer and postReducer.</strong></p><p name="7f21" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 6: Create a Redux Store.</strong></p><p name="4aa6" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 7: Pass the Store to the React Native app.</strong></p><p name="0615" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 8: Connect React Native app to Redux store.</strong></p><p name="c35e" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 9: Test your app</strong></p><p name="aff6" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Step 10: What is the basic difference between redux-thunk and redux-saga?</strong></p><p name="5302" class="graf graf--p graf-after--p">So let’s dive right in!</p><figure tabindex="0" contenteditable="false" name="feb4" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 320px; max-height: 240px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 75%;"></div><img class="graf-image" data-image-id="1*HfUjPCVB8Eer3q22lcuoew.gif" data-width="320" data-height="240" src="https://cdn-images-1.medium.com/max/800/1*HfUjPCVB8Eer3q22lcuoew.gif"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Ouch! Let’s&nbsp;….. not&nbsp;dive</figcaption></figure><h3 name="7bdf" class="graf graf--h3 graf-after--figure">1. Create a basic React Native&nbsp;app</h3><p name="f682" class="graf graf--p graf-after--h3">First, make sure you have all pre-requisites to create a react-native app as per the <a href="https://facebook.github.io/react-native/docs/getting-started.html"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">official documentation</a>.</p><blockquote name="cc11" class="graf graf--blockquote graf-after--p"><strong class="markup--strong markup--blockquote-strong">At the time of this post, I have React-Native version 0.60</strong></blockquote><p name="2507" class="graf graf--p graf-after--blockquote">Create a blank react-native app (Replace <code class="markup--code markup--p-code">myApp</code> with your own name)</p><pre name="2cb3" class="graf graf--pre graf-after--p">$ react-native init myApp</pre><p name="c53e" class="graf graf--p graf-after--pre">This will create a basic React-native app which you can run in a device or simulator. (either Android or iOS)</p><h3 name="de1e" class="graf graf--h3 graf-after--p">Step 2: Running app on&nbsp;device</h3><p name="437c" class="graf graf--p graf-after--h3">To run the iOS app, you should specify simulator</p><pre name="a143" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">react-native run-ios --simulator=”iPhone X”</code></pre><p name="03c1" class="graf graf--p graf-after--pre">To run Android app, you should start emulator first, either via Android Studio or <code class="markup--code markup--p-code">adb</code>&nbsp;, then call</p><pre name="ced5" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">react-native run-android</code></pre><p name="ba77" class="graf graf--p graf-after--pre">You’ll see the default start screen</p><figure tabindex="0" contenteditable="false" name="c76c" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 350px; max-height: 622px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 177.7%;"></div><img class="graf-image" data-image-id="1*TnZfGsKdsWGBUac-0YutpA.jpeg" data-width="350" data-height="622" src="https://cdn-images-1.medium.com/max/800/1*TnZfGsKdsWGBUac-0YutpA.jpeg"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Default start screen for React Native&nbsp;app</figcaption></figure><h3 name="46c8" class="graf graf--h3 graf-after--figure"><strong class="markup--strong markup--h3-strong">Step 3: Install the necessary packages to connect your app with&nbsp;redux.</strong></h3><p name="aa24" class="graf graf--p graf-after--h3"><strong class="markup--strong markup--p-strong">npm</strong></p><pre name="af6e" class="graf graf--pre graf-after--p">npm install redux react-redux redux-thunk</pre><p name="31f3" class="graf graf--p graf-after--pre"><strong class="markup--strong markup--p-strong">yarn</strong></p><pre name="12d9" class="graf graf--pre graf-after--p">yarn add redux react-redux redux-thunk</pre><blockquote name="2459" class="graf graf--blockquote graf-after--pre"><a href="https://github.com/reduxjs/react-redux"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank">React Redux</a> is the official <a href="https://reactjs.org/"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank">React</a> binding for <a href="https://redux.js.org/"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank">Redux</a>. It lets your React components read data from a Redux store, and dispatch actions to the store to update data.</blockquote><blockquote name="df5b" class="graf graf--blockquote graf-after--blockquote">As of React Native 0.18, React Redux 5.x should work with React Native. If you have any issues with React Redux 5.x on React Native, run <code class="markup--code markup--blockquote-code"><em class="markup--em markup--blockquote-em">npm ls react</em></code> and make sure you don’t have a duplicate React installation in your <code class="markup--code markup--blockquote-code"><em class="markup--em markup--blockquote-em">node_modules</em></code>. We recommend that you use <code class="markup--code markup--blockquote-code"><em class="markup--em markup--blockquote-em">npm@3.x</em></code>which is better at avoiding these kinds of issues.</blockquote><p name="67e3" class="graf graf--p graf-after--blockquote">The React Redux docs are now published at <a href="https://react-redux.js.org/"  class="markup--anchor markup--p-anchor" rel="nofollow noopener"    target="_blank">https://react-redux.js.org</a>&nbsp;.</p><p name="9f0c" class="graf graf--p graf-after--p">If you want to know how it works, check out <a href="https://www.youtube.com/watch?v=VJ38wSFbM3A"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">this link</a></p><h3 name="5015" class="graf graf--h3 graf-after--p">Step 5: Create the necessary folders inside&nbsp;Root</h3><p name="041e" class="graf graf--p graf-after--h3">Let’s keep this image in mind to help us understand which parts of Redux are implemented at what step.</p><figure tabindex="0" contenteditable="false" name="2f85" class="graf graf--figure graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked" style="max-width: 541px; max-height: 295px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 54.50000000000001%;"></div><img class="graf-image" data-image-id="1*Q3QdBDZL4cBrR5GXT6J5jA.jpeg" data-width="541" data-height="295" src="https://cdn-images-1.medium.com/max/800/1*Q3QdBDZL4cBrR5GXT6J5jA.jpeg"><div class="crosshair u-ignoreBlock"></div></div></figure><p name="5695" class="graf graf--p graf-after--figure">To work with redux you can follow this folder structure for better code quality</p><p name="caaa" class="graf graf--p graf-after--p">Create the following folders.</p><ol class="postList"><li name="98ae" class="graf graf--li graf-after--p"><strong class="markup--strong markup--li-strong">actions</strong></li><li name="56f5" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">constants</strong></li><li name="f2ee" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">reducers</strong></li><li name="cc5e" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">components</strong></li></ol><h3 name="bed4" class="graf graf--h3 graf-after--li">Step 6: Create Constants and&nbsp;Actions</h3><p name="11be" class="graf graf--p graf-after--h3"><strong class="markup--strong markup--p-strong">6.1</strong> Inside the <code class="markup--code markup--p-code">constants</code> folder, create one file called <strong class="markup--strong markup--p-strong">index.js. </strong>Add the following line inside <strong class="markup--strong markup--p-strong">index.js.</strong></p><pre name="8552" class="graf graf--pre graf-after--p">const GET_PAGE_LIST = 'GET_PAGE_LIST';</pre><p name="9caf" class="graf graf--p graf-after--pre"><strong class="markup--strong markup--p-strong">6.2</strong> Inside the <strong class="markup--strong markup--p-strong">actions </strong>folder, create one file called <strong class="markup--strong markup--p-strong">pageList.js. </strong>Add the following code inside <strong class="markup--strong markup--p-strong">pageList.js.</strong></p><p name="3f0f" class="graf graf--p graf-after--p"><code class="markup--code markup--p-code">Actions</code> are JavaScript objects that represent payloads of information that send data from your application to your <code class="markup--code markup--p-code">Redux</code> store.</p><p name="dbfc" class="graf graf--p graf-after--p">Actions have a type and an optional payload. In our case, the type will be <code class="markup--code markup--p-code">GET_PAGE_LIST</code> and the payload <code class="markup--code markup--p-code">pageList</code> which we are assigning into our <code class="markup--code markup--p-code">pageList</code> variable in store.</p><pre name="30e2" class="graf graf--pre graf-after--p">import { GET_PAGE_LIST } from '../constants';</pre><pre name="fcd8" class="graf graf--pre graf-after--pre">export function setPageList(pageList) {</pre><pre name="417e" class="graf graf--pre graf-after--pre">return {</pre><pre name="f9b7" class="graf graf--pre graf-after--pre">type: GET_PAGE_LIST,</pre><pre name="ddea" class="graf graf--pre graf-after--pre">payload: pageList,</pre><pre name="d18b" class="graf graf--pre graf-after--pre">};</pre><pre name="6074" class="graf graf--pre graf-after--pre">}</pre><pre name="7557" class="graf graf--pre graf-after--pre">export function getPageList() {</pre><pre name="4e53" class="graf graf--pre graf-after--pre">return async (dispatch) =&gt; {</pre><pre name="c601" class="graf graf--pre graf-after--pre">try {</pre><pre name="1039" class="graf graf--pre graf-after--pre">const apiReq = await fetch('http://dummy.restapiexample.com/api/v1/employees', {</pre><pre name="6ddb" class="graf graf--pre graf-after--pre">method: 'GET'</pre><pre name="dc62" class="graf graf--pre graf-after--pre">});</pre><pre name="9dfd" class="graf graf--pre graf-after--pre">console.log(apiReq);</pre><pre name="14ec" class="graf graf--pre graf-after--pre">await dispatch(setPageList(apiReq));</pre><pre name="949b" class="graf graf--pre graf-after--pre">return apiReq || [];</pre><pre name="fa25" class="graf graf--pre graf-after--pre">} catch (error) {</pre><pre name="fbb2" class="graf graf--pre graf-after--pre">console.error(error);</pre><pre name="231e" class="graf graf--pre graf-after--pre">}</pre><pre name="c1eb" class="graf graf--pre graf-after--pre">};</pre><pre name="b379" class="graf graf--pre graf-after--pre">}</pre><p name="67ad" class="graf graf--p graf-after--pre">So, here we have defined an action that calls the API and gets a response from the server. Remember, the reducer is a pure function, and we do not want any asynchronous call inside reducer, all the asynchronous actions are called here inside actions.</p><p name="5c8b" class="graf graf--p graf-after--p">But, we need to connect this action to our <code class="markup--code markup--p-code">App.js</code> component somehow. Otherwise, we cannot add the data into the Redux store. Also, we need to first create a store. But before that, we also need to create a reducer function. So, first, create a reducer → then create a store and → then connect the React Native application to the <strong class="markup--strong markup--p-strong">Redux</strong> store.</p><figure tabindex="0" contenteditable="false" name="3c4e" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 541px; max-height: 295px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 54.50000000000001%;"></div><img class="graf-image" data-image-id="1*Au_jHh1Ytm-WazqHqB1J-g.jpeg" data-width="541" data-height="295" src="https://cdn-images-1.medium.com/max/800/1*Au_jHh1Ytm-WazqHqB1J-g.jpeg"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Actions created&nbsp;…</figcaption></figure><h3 name="6937" class="graf graf--h3 graf-after--figure"><strong class="markup--strong markup--h3-strong">Step 6:- Create rootReducer and postReducer.</strong></h3><p name="69e1" class="graf graf--p graf-after--h3">Now, inside the <strong class="markup--strong markup--p-strong">reducers folder, </strong>create one file called <strong class="markup--strong markup--p-strong">pageList.js.</strong></p><p name="bd39" class="graf graf--p graf-after--p">Write the following code inside the <strong class="markup--strong markup--p-strong">pageListReducer.js</strong>.</p><pre name="20b7" class="graf graf--pre graf-after--p">import { GET_PAGE_LIST } from '../constants';</pre><pre name="dd92" class="graf graf--pre graf-after--pre">const initialState = {<br>pageList: []<br>};</pre><pre name="8d9d" class="graf graf--pre graf-after--pre">const <strong class="markup--strong markup--pre-strong">pageListReducer </strong>= (state = initialState, action) =&gt; {<br>switch(action.type) {<br>case GET_PAGE_LIST:<br>return {<br>...state,<br>pageList: []<br>};<br>default:<br>return state;<br>}<br>}</pre><pre name="15af" class="graf graf--pre graf-after--pre">export default <strong class="markup--strong markup--pre-strong">pageListReducer</strong>;</pre><p name="d26a" class="graf graf--p graf-after--pre">So, here, we have defined the function called <strong class="markup--strong markup--p-strong">pageListReducer </strong>that accepts the two arguments.</p><ol class="postList"><li name="fbbd" class="graf graf--li graf-after--p"><strong class="markup--strong markup--li-strong">state</strong></li><li name="c952" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">action</strong></li></ol><p name="97e5" class="graf graf--p graf-after--li">The first time, it will take the <strong class="markup--strong markup--p-strong">initial state</strong> of our application, and then we pass whatever argument, it takes that argument and operates based on the case execution. The second argument is <strong class="markup--strong markup--p-strong">action, </strong>which consists of <strong class="markup--strong markup--p-strong">type </strong>and <strong class="markup--strong markup--p-strong">payload. </strong>The <strong class="markup--strong markup--p-strong">payload</strong> is the count value, which assigned to count variable in store.</p><p name="87e6" class="graf graf--p graf-after--p">Remember here&#8202;—&#8202;we have returned a new state and not existing state. So we have modified the state in a pure manner.</p><figure tabindex="0" contenteditable="false" name="2155" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 541px; max-height: 295px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 54.50000000000001%;"></div><img class="graf-image" data-image-id="1*Lm-NV5s_pxehZXR58XOM9w.jpeg" data-width="541" data-height="295" src="https://cdn-images-1.medium.com/max/800/1*Lm-NV5s_pxehZXR58XOM9w.jpeg"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Actions and reducer&nbsp;created</figcaption></figure><h3 name="8682" class="graf graf--h3 graf-after--figure">Step 7:-Create a Redux&nbsp;Store.</h3><p name="f2dd" class="graf graf--p graf-after--h3">Inside the root folder, create one folder called <strong class="markup--strong markup--p-strong">store </strong>and inside this folder add one file called <code class="markup--code markup--p-code">configureStore.js</code> add the following code.</p><pre name="31ec" class="graf graf--pre graf-after--p">import { createStore, combineReducers } from 'redux';</pre><pre name="3753" class="graf graf--pre graf-after--pre">import pageReducer from '../reducers/pageReducer';</pre><pre name="cc95" class="graf graf--pre graf-after--pre">import { applyMiddleware } from 'redux';</pre><pre name="71e6" class="graf graf--pre graf-after--pre">import thunk from 'redux-thunk';</pre><pre name="f4dd" class="graf graf--pre graf-after--pre">const rootReducer = combineReducers(</pre><pre name="72bb" class="graf graf--pre graf-after--pre">{ pageList: pageReducer }</pre><pre name="efcb" class="graf graf--pre graf-after--pre">);</pre><pre name="18a4" class="graf graf--pre graf-after--pre">const configureStore = () =&gt; {</pre><pre name="eb77" class="graf graf--pre graf-after--pre">return createStore(rootReducer, applyMiddleware(thunk));</pre><pre name="81c9" class="graf graf--pre graf-after--pre">}</pre><pre name="57d0" class="graf graf--pre graf-after--pre">export default configureStore;</pre><p name="0dd1" class="graf graf--p graf-after--pre">Here, we have created the redux store and passed the reducer to that store. This store will ideally contain all the data that handles the app state.</p><p name="1ec6" class="graf graf--p graf-after--p">The <strong class="markup--strong markup--p-strong">combineReducer </strong>function combines all the different reducers into one and forms the global state. So this is the global state of our whole application.</p><figure tabindex="0" contenteditable="false" name="47b9" class="graf graf--figure graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked" style="max-width: 541px; max-height: 295px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 54.50000000000001%;"></div><img class="graf-image" data-image-id="1*5T_3GIKODoO03mrqakOULw.jpeg" data-width="541" data-height="295" src="https://cdn-images-1.medium.com/max/800/1*5T_3GIKODoO03mrqakOULw.jpeg"><div class="crosshair u-ignoreBlock"></div></div></figure><h3 name="3c2a" class="graf graf--h3 graf-after--figure">Step 8: Pass the Store to the React Native&nbsp;app.</h3><p name="6bb9" class="graf graf--p graf-after--h3">Inside the root folder, you will find one file called <strong class="markup--strong markup--p-strong">index.js </strong>and inside that file add the following code.</p><figure tabindex="0" contenteditable="false" name="b607" class="graf graf--figure graf--iframe graf-after--p"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 35.699999999999996%;"></div><div class="iframeContainer">{% gist https://gist.github.com/enappd/62f0ac568370eaf0674bea7db8b92b89.js %}</div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for embed (optional)">Index.js</figcaption></figure><p name="c762" class="graf graf--p graf-after--figure">It is almost the same as React web application, in which we pass the Provider as a root element and pass the store and then via react-redux’s <strong class="markup--strong markup--p-strong">connect</strong>() function, we can <strong class="markup--strong markup--p-strong">connect</strong> the any react component to <strong class="markup--strong markup--p-strong">redux</strong> store.</p><figure tabindex="0" contenteditable="false" name="aec6" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 541px; max-height: 295px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 54.50000000000001%;"></div><img class="graf-image" data-image-id="1*6kh_Lwo9EKVfsaZKtw3oTw.jpeg" data-width="541" data-height="295" src="https://cdn-images-1.medium.com/max/800/1*6kh_Lwo9EKVfsaZKtw3oTw.jpeg"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Store connected to the&nbsp;app</figcaption></figure><h3 name="f9ad" class="graf graf--h3 graf-after--figure"><strong class="markup--strong markup--h3-strong">Step 8: Connect React Native app to Redux&nbsp;store.</strong></h3><p name="88d0" class="graf graf--p graf-after--h3">Finally, we connect our <strong class="markup--strong markup--p-strong">App.js </strong>component to the <strong class="markup--strong markup--p-strong">Redux</strong> store. For that, we need the <strong class="markup--strong markup--p-strong">connect() </strong>function from the<strong class="markup--strong markup--p-strong"> react-redux</strong> library.</p><figure tabindex="0" contenteditable="false" name="202f" class="graf graf--figure graf--iframe graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 35.699999999999996%;"></div><div class="iframeContainer">{% gist https://gist.github.com/enappd/41688358d912236184481ba42453c81c.js %}</div></div></figure><p name="0c16" class="graf graf--p graf-after--figure"><strong class="markup--strong markup--p-strong">Connect</strong> which needs to be imported from <em class="markup--em markup--p-em">react-redux </em>and with the help of connect the properties will be mapped to the UI component.</p><p name="976b" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">mapStateToProps </strong>will contain all the state properties which will be available to the components of the app whatever properties that need to be accessed from the UI components need to be written into the <strong class="markup--strong markup--p-strong">mapStateToProps </strong>helper function.</p><p name="f00f" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">mapDispatchToProps </strong>will contain all the necessary functions wrapped with action creators which will be mapped to the props of the app and can be called directly. The directory containing the below file is&nbsp;<code class="markup--code markup--p-code">./actions/pageList.js</code></p><p name="eef5" class="graf graf--p graf-after--p">Here, when we click on the get employee button, we get the Employees value from props and change it and then send it to the action with that value. Now that action returned the object with the action type and payload and based on the type the reducer will be executed and add that values inside the store.</p><p name="465a" class="graf graf--p graf-after--p">Now, if the store’s values are changed, then we need to update the UI based on the new values. That is why <strong class="markup--strong markup--p-strong">the mapStateToProps </strong>function is created. So, when the store’s count get the new value, render function executed again and update the UI.</p><h3 name="0a10" class="graf graf--h3 graf-after--p">Step 10: Test your&nbsp;app:</h3><p name="8b15" class="graf graf--p graf-after--h3">Once you run the application the below UI will be rendered.</p><figure tabindex="0" contenteditable="false" name="1457" class="graf graf--figure graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked" style="max-width: 300px; max-height: 600px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 200%;"></div><img class="graf-image" data-image-id="1*7OV5yCea4w2qv9xDT6Cb-g.jpeg" data-width="300" data-height="600" src="https://cdn-images-1.medium.com/max/800/1*7OV5yCea4w2qv9xDT6Cb-g.jpeg"><div class="crosshair u-ignoreBlock"></div></div></figure><p name="dd85" class="graf graf--p graf-after--figure">Once you click on any of the get employe buttons it will correctly fetch data from a server and render it on UI. Although, what we just did is nothing fancy for an app, remember everything is going through the whole <strong class="markup--strong markup--p-strong">“action-reducer-store-state”</strong> flow. This flow can handle large and complex apps, so you don’t get stuck in<strong class="markup--strong markup--p-strong"> “props” </strong>loops.</p><figure tabindex="0" contenteditable="false" name="1d6e" class="graf graf--figure graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked" style="max-width: 300px; max-height: 600px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 200%;"></div><img class="graf-image" data-image-id="1*3FxIFMjmE0Bj2KyWxtp2BA.jpeg" data-width="300" data-height="600" src="https://cdn-images-1.medium.com/max/800/1*3FxIFMjmE0Bj2KyWxtp2BA.jpeg"><div class="crosshair u-ignoreBlock"></div></div></figure><p name="2a36" class="graf graf--p graf-after--figure">(If you are from an <strong class="markup--strong markup--p-strong">Angular</strong> background, for ease of understanding, you can understand <code class="markup--code markup--p-code">actions</code> as something similar to methods in <code class="markup--code markup--p-code">services</code> which we can call from any component or page. <code class="markup--code markup--p-code">Reducers</code> are also similar functions, but they change the central store of the app. <code class="markup--code markup--p-code">Store</code> can be assumed as something similar to a <code class="markup--code markup--p-code">$rootscope </code>object which stores all the data at one place, and can be accessed from any page. Don’t draw a direct comparison between these things, this is just to help you understand the concept in an easier way.)</p><p name="21b3" class="graf graf--p graf-after--p">Hope this blog helps you to implement redux with middleware (thunk) in react native apps.</p><h3 name="6526" class="graf graf--h3 graf-after--p"><strong class="markup--strong markup--h3-strong">Step 10: What is the basic difference between redux-thunk and redux-saga?</strong></h3><p name="5d5a" class="graf graf--p graf-after--h3">In terms of implementation, Redux-Thunk and Redux-Saga couldn’t possibly be more different. However, in terms of what you can do with them… well, they’re actually very very similar. But not the same. Redux-Thunk and Redux-Saga differ in a few important ways.</p><p name="3a58" class="graf graf--p graf-after--p">But, first, let’s cover some background.</p><p name="87bd" class="graf graf--p graf-after--p">Redux-thunk and Redux-saga are both <a href="https://redux.js.org/advanced/middleware"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">middleware</a> libraries for Redux. Redux middleware is code that intercepts actions coming into the store via the <code class="markup--code markup--p-code">dispatch()</code> method.</p><p name="7a81" class="graf graf--p graf-after--p">An action can be literally anything.</p><p name="2ff1" class="graf graf--p graf-after--p">But if you’re following best practices, an action is a plain javascript object with a <code class="markup--code markup--p-code">type</code> field, and optional <code class="markup--code markup--p-code">payload</code>, <code class="markup--code markup--p-code">meta</code>, and <code class="markup--code markup--p-code">error</code> fields. E.g.</p><pre name="c9da" class="graf graf--pre graf-after--p">const loginRequest = {</pre><pre name="046d" class="graf graf--pre graf-after--pre">type: 'LOGIN_REQUEST',</pre><pre name="2ec8" class="graf graf--pre graf-after--pre">payload: {</pre><pre name="48ea" class="graf graf--pre graf-after--pre">name: 'admin',</pre><pre name="df97" class="graf graf--pre graf-after--pre">password: '123',</pre><pre name="87a5" class="graf graf--pre graf-after--pre">},</pre><pre name="15e0" class="graf graf--pre graf-after--pre">};</pre><p name="3c11" class="graf graf--p graf-after--pre">(by the way, this structure is called <a href="https://github.com/acdlite/flux-standard-action#actions"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Flux Standard Action</a>)</p><p name="1b38" class="graf graf--p graf-after--p">This is what the type signature looks like in TypeScript</p><pre name="58fd" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">type Action = {    <br>     type: string;    <br>     payload?: any;    <br>     meta?: any;    <br>     error?: boolean;<br>};</code></pre><h3 name="65f1" class="graf graf--h3 graf-after--pre">Redux-Thunk</h3><p name="e1c4" class="graf graf--p graf-after--h3">In addition to dispatching standard actions, Redux-Thunk middleware allows you to dispatch special functions, called <a href="https://en.wikipedia.org/wiki/Thunk"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">thunks</a>.</p><p name="c508" class="graf graf--p graf-after--p">Thunks (in Redux) generally have the following structure:</p><pre name="7f8d" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">export const thunkName =   parameters =&gt;   <br>     (dispatch, getState) =&gt; {         <br>   // Your application logic goes here      <br> };</code></pre><p name="9302" class="graf graf--p graf-after--pre">That is, a thunk is a function that (optionally) takes some parameters and returns another function. The inner function takes a <code class="markup--code markup--p-code">dispatch</code> function and a <code class="markup--code markup--p-code">getState</code> function -- both of which will be supplied by the Redux-Thunk middleware.</p><p name="d6f8" class="graf graf--p graf-after--p">Here we have an example thunk that attempts to call a login API with a username and password. The thunk first dispatches an action indicating that the request is starting. It then makes the call. Finally, it dispatches either a success action or a failure action depending on whether or not the API call succeeded.</p><pre name="fb38" class="graf graf--pre graf-after--p">import * as api from 'api';</pre><pre name="1b05" class="graf graf--pre graf-after--pre">import { loginRequest, loginSuccess, loginFailure } from './loginActions';</pre><pre name="a2d6" class="graf graf--pre graf-after--pre">export const loginThunk =</pre><pre name="38f4" class="graf graf--pre graf-after--pre">(name: string, password: string) =&gt;</pre><pre name="233c" class="graf graf--pre graf-after--pre">(dispatch: Function) =&gt; {</pre><pre name="91d9" class="graf graf--pre graf-after--pre">   dispatch(loginRequest());</pre><pre name="a820" class="graf graf--pre graf-after--pre">   try {</pre><pre name="8e0a" class="graf graf--pre graf-after--pre">      api.login(name, password);</pre><pre name="2f5a" class="graf graf--pre graf-after--pre">   }catch (err) {</pre><pre name="7426" class="graf graf--pre graf-after--pre">     dispatch(loginFailure(err));</pre><pre name="fcdf" class="graf graf--pre graf-after--pre">     return;</pre><pre name="84ac" class="graf graf--pre graf-after--pre">   }</pre><pre name="660c" class="graf graf--pre graf-after--pre">   dispatch(loginSuccess());</pre><pre name="eb8e" class="graf graf--pre graf-after--pre">};</pre><p name="9e78" class="graf graf--p graf-after--pre">When you dispatch your thunk, e.g. <code class="markup--code markup--p-code">dispatch(loginThunk('admin', 'secret'));</code> Redux-Thunk calls your inner function, which is essentially:</p><pre name="4774" class="graf graf--pre graf-after--p">(dispatch: Function) =&gt; {</pre><pre name="c896" class="graf graf--pre graf-after--pre">  dispatch(loginRequest());</pre><pre name="dda3" class="graf graf--pre graf-after--pre">  try {</pre><pre name="2689" class="graf graf--pre graf-after--pre">     api.login('admin', 'secret'); // values from closure</pre><pre name="fd47" class="graf graf--pre graf-after--pre">  }catch (err) {</pre><pre name="a680" class="graf graf--pre graf-after--pre">    dispatch(loginFailure(err));</pre><pre name="f017" class="graf graf--pre graf-after--pre">    return;</pre><pre name="dfe2" class="graf graf--pre graf-after--pre">  }</pre><pre name="d011" class="graf graf--pre graf-after--pre">  dispatch(loginSuccess());</pre><pre name="b034" class="graf graf--pre graf-after--pre">};</pre><p name="f0f5" class="graf graf--p graf-after--pre">Now that we’ve covered the basics of Redux-thunk, let’s look at Redux-Saga</p><h3 name="a9ef" class="graf graf--h3 graf-after--p">Redux-Saga</h3><p name="dde6" class="graf graf--p graf-after--h3">Redux-Saga middleware allows you to express complex application logic as <a href="https://en.wikipedia.org/wiki/Pure_function"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">pure functions</a> called sagas. Pure functions are desirable from a testing standpoint because they are predictable and repeatable, which makes them relatively easy to test.</p><p name="0b73" class="graf graf--p graf-after--p">Sagas are implemented through special functions called <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function%252A"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">generator functions</a>. These are a new feature of ES6 JavaScript. Basically, execution jumps in and out of a generator everywhere you see a <code class="markup--code markup--p-code">yield</code>statement. Think of a <code class="markup--code markup--p-code">yield</code> statement as causing the generator to pause and return the yielded value. Later on, the caller can resume the generator at the statement following the <code class="markup--code markup--p-code">yield</code>.</p><p name="4cf4" class="graf graf--p graf-after--p">A generator function is one defined like this. Notice the asterisk after the function keyword.</p><pre name="59f6" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">function* mySaga() {    // ...}</code></pre><p name="4934" class="graf graf--p graf-after--pre">We can rewrite the login functionality from before as a saga. It looks like this:</p><pre name="6a8f" class="graf graf--pre graf-after--p">import * as api from 'api';</pre><pre name="fbd3" class="graf graf--pre graf-after--pre">import { LoginRequestAction, loginSuccess, loginFailure } from './loginActions';</pre><pre name="9104" class="graf graf--pre graf-after--pre">function* loginSaga() {</pre><pre name="886e" class="graf graf--pre graf-after--pre">const action: LoginRequestAction = yield take('LOGIN_REQUEST');</pre><pre name="3978" class="graf graf--pre graf-after--pre">const { name, password } = action.payload;</pre><pre name="b74b" class="graf graf--pre graf-after--pre">try {</pre><pre name="b27e" class="graf graf--pre graf-after--pre">yield call(api.login, name, password);</pre><pre name="2808" class="graf graf--pre graf-after--pre">}</pre><pre name="e1e7" class="graf graf--pre graf-after--pre">catch (err) {</pre><pre name="2c20" class="graf graf--pre graf-after--pre">yield put(loginFailure(err));</pre><pre name="f21d" class="graf graf--pre graf-after--pre">return;</pre><pre name="5a62" class="graf graf--pre graf-after--pre">}</pre><pre name="b3dc" class="graf graf--pre graf-after--pre">yield put(loginSuccess());</pre><pre name="edc9" class="graf graf--pre graf-after--pre">}</pre><p name="0aed" class="graf graf--p graf-after--pre">Once the login saga is registered with Redux-Saga, it will begin executing immediately. But then the <code class="markup--code markup--p-code">yield take</code> on the the first line will pause the saga until an action with type <code class="markup--code markup--p-code">'LOGIN_REQUEST'</code> is dispatched to the store. Once that happens, execution will continue.</p><h3 name="653d" class="graf graf--h3 graf-after--p">The Biggest Difference</h3><p name="000a" class="graf graf--p graf-after--h3">You might think the biggest difference is in the syntax. Although it’s true that writing and reasoning about thunks and sagas are quite different, there’s something bigger.</p><p name="5f62" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Thunks can never act in response to an action.</strong> Redux-Saga, on the other hand, subscribes to the store and can trigger a saga to run or continue when a certain action is dispatched.</p><h3 name="d3ec" class="graf graf--h3 graf-after--p">Conclusion</h3><p name="adcf" class="graf graf--p graf-after--h3">In this post, you learned how to implement Redux with middleware(redux-thunk) in your React Native app. You learnt what are reducers, actions, and store, how the flow of data is managed in a Redux based app.</p><figure tabindex="0" contenteditable="false" name="c10f" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 480px; max-height: 348px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 72.5%;"></div><img class="graf-image" data-image-id="1*ceLX14cSsAZ-M7c2GHdlSA.gif" data-width="480" data-height="348" src="https://cdn-images-1.medium.com/max/800/1*ceLX14cSsAZ-M7c2GHdlSA.gif"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Now, chill</figcaption></figure><p name="a879" class="graf graf--p graf-after--figure">And that’s it! The application now uses Redux and Redux Thunk to fetch and display the data!</p><p name="22bc" class="graf graf--p graf-after--p">That wasn’t too difficult, was it?</p><p name="0d60" class="graf graf--p graf-after--p">And you’re now a Redux master&nbsp;:D</p><p name="8331" class="graf graf--p graf-after--p">Stay tuned for more Ionic and React Native blogs!</p><p name="7a72" class="graf graf--p graf-after--p">Happy Coding.🤓👍🏼</p><blockquote name="e406" class="graf graf--blockquote graf-after--p"><em class="markup--em markup--blockquote-em">Complete source code of this tutorial is available in the </em><a href="https://github.com/enappd/react-native-redux-thunk.git"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank">React-native-redux-thunk-example</a></blockquote><h3 name="0fac" class="graf graf--h3 graf-after--blockquote">Next Steps</h3><p name="0993" class="graf graf--p graf-after--h3">Now that you have learnt about setting up Redux with middleware(redux-thunk) in React Native apps, here are some other topics you can look into</p><ul class="postList"><li name="6f8d" class="graf graf--li graf-after--p">Firebase&#8202;—&#8202;<a href="https://enappd.com/blog/intergrate-firebase-in-react-native-app/73"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener noopener"    target="_blank">Integrate Firebase</a> | <a href="https://enappd.com/blog/firebase-analytics-in-react-native-app/101"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Analytics</a> | <a href="https://enappd.com/blog/react-native-firebase-crud-image-upload-and-phone-authentication/86"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener noopener"    target="_blank">Push notifications</a> | <a href="https://enappd.com/blog/react-native-firebase-crud-image-upload-and-phone-authentication/86"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener noopener"    target="_blank">Firebase CRUD</a></li><li name="ce44" class="graf graf--li graf-after--li">How To in React Native&#8202;—&#8202;<a href="https://enappd.com/blog/geolocation-geocoding-react-native-apps/84"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Geolocation</a> | <a href="https://enappd.com/blog/react-native-life-cycle-hooks/79"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Life cycle hooks</a> | <a href="https://enappd.com/blog/pick-images-from-camera-gallery-in-react-native-app/78"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Image Picker</a> | <a href="https://enappd.com/blog/redux-in-react-native-app/92"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Redux implementation</a> | <a href="https://enappd.com/blog/how-to-make-api-calls-in-react-native-apps/125"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Make API calls</a> | <a href="https://enappd.com/blog/navigations-in-react-native-app/124"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Navigation</a> | <a href="https://enappd.com/blog/how-to-translate-in-react-native-app-globalization-internationalization-and-text-to-speech/120"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Translation</a> | <a href="https://enappd.com/blog/react-native-qr-code-scanning-using-react-native-camera/117"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Barcode &amp; QR code scan</a> | <a href="https://enappd.com/blog/send-read-and-delete-sms-in-react-native/107"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Send &amp; Read SMS</a> | <a href="https://enappd.com/blog/google-vision-with-react-native/96"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Google Vision</a></li><li name="e480" class="graf graf--li graf-after--li">Payments&#8202;—&#8202;<a href="https://enappd.com/blog/implement-apple-pay-in-react-native-apps/93"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Apple Pay</a> | <a href="https://enappd.com/blog/stripe-integration-in-react-native-apps-using-firebase/108"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Stripe payments</a></li><li name="4d3b" class="graf graf--li graf-after--li">Authentication&#8202;—&#8202;<a href="https://enappd.com/blog/google-login-in-react-native-android-apps-with-firebase/90"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Google Login</a>| <a href="https://enappd.com/blog/facebook-login-in-react-native-apps/89"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Facebook login</a> | <a href="https://enappd.com/blog/react-native-firebase-crud-image-upload-and-phone-authentication/86"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Phone Auth</a> | <a href="https://enappd.com/blog/twitter-login-in-react-native-apps-using-firebase/95"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Twitter login</a> | <a href="https://enappd.com/blog/anonymous-login-in-react-native-apps-with-firebase/129"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Anonymous Login</a></li><li name="2ccd" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/how-to-make-stories-ui-like-instagram-and-whatsapp-in-react-native/123"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Create Instagram / Whatsapp Story Feature in React Native</a></li><li name="01c3" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/react-native-life-cycle-hooks/79"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener noopener"    target="_blank">React Native life cycle hooks</a> | <a href="https://enappd.com/blog/redux-in-react-native-app/92"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Implement Redux</a> | <a href="https://enappd.com/blog/async-actions-with-redux-thunk-middleware-in-react-native-apps-1/100"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Async actions with Redux</a></li><li name="8db9" class="graf graf--li graf-after--li"><a href="https://enappd.com/blog/guide-on-react-native-full-app/53"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Create Awesome Apps in React Native</a> using Full App</li></ul><p name="28d0" class="graf graf--p graf-after--li">If you need a base to start your next React Native app, you can make your next awesome app using <a href="https://store.enappd.com/product/react-native-full-app/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">React Native Full App</a></p><figure tabindex="0" contenteditable="false" name="e4d4" class="graf graf--figure graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 700px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 100%;"></div><img class="graf-image" data-image-id="1*sWyEeAfCMk7ULOkLUCdSug.jpeg" data-width="800" data-height="800" src="https://cdn-images-1.medium.com/max/800/1*sWyEeAfCMk7ULOkLUCdSug.jpeg"><div class="crosshair u-ignoreBlock"></div></div></figure><p name="9e45" class="graf graf--p graf--empty graf-after--figure graf--trailing"><br></p></div></div></section></div></article></main>