React Native + Redux + Redux-Saga as application architecture.

Aleksei Jegorov
Feb 1 · 6 min read

Some practical aspects of Redux and Redux-Saga I have worked with.

Since React v16.8.0 a lot of Hooks becomes available. It simplifies life.

Hooks let you use more of React’s features without classes. Hooks provide a more direct API to the React concepts you already know: props, state, context, refs (access to object by id reference), and lifecycle.

I. Practical Task to be implemented: integrate Google map into React Native application. Let’s look on Android part. iOS part missed to make compact article.

0. Create new React Native project in Intellij IDEA or Visual Studio Code

  1. Install npm or yarn on your computer and run following command

npm install — save react-native-maps

or yarn add react-native-maps

2. for Android version, we need to add meta tag to Android.manifest

<uses-permission android:name=”android.permission.ACCESS_COARSE_LOCATION” />
<uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION” />

<meta-data
android:name=”com.google.android.geo.API_KEY”
android:value=”Google Api key”/>

3. Also, need to handle android permission correctly in Activity java file.

4. When new npm libraries added to the project it also need to run some clean commands in /android/ folder. Run in console:

gradlew clean
npm start — — reset-cache

5. We has to download remote stored data using standard way with Axios library. Also, let’s implement an easy loop cycle that will update in an interval of 1 minute.

6. The code above is very straightforward: it mix implementation logic and the View together. Let’s split them out with help of Redux and Redux-Saga.

I prefer to think about Redux-Saga as a separate thread to run asynchronous scenarios in background mode and return result to the Component View.

Redux looks like a MVC approach. Component is a View UI, Action is a Controller, Reducer is a Model (hold the current state) and Redux-Saga works as a background service. Store is like a container for the state that aggregates all of the reducers.

Redux it is just a state container that supports the asynchronous approach. When an action occurs, the object sends to the store, after that reducer being called and he refreshes the state.

In case of asynchronous approach Redux uses middlewares Redux-Saga layers. It runs after the action, but before the reducer being called.

7. In main.js file plug Root Saga from saga.js to the store using applyMiddleware function.

8. In the beginning, we has to define the root. Root Saga just combine together our generators (sagas):

Saga implemented as middleware which control asynchronous side effects.

Redux-saga do it with help of ES6 generators. Generators are the functions that could be paused or resumes when necessary. Generator will execute code until it found yield keyword.

If on the other hand you need to cancel the saga when something happens from the outside (timeout happens or user action) then it makes sense to use the yield race keyword.

yield put keyword tells Redux-Saga that this action should be dispatched.

The yield take keyword causes the Redux-Saga to block until the specified action gets dispatched. Note, this does not block your UI or any other processing on your page.

9. Now we define endless loop to download data from time to time.

10. It is the time to work with Redux.

Our Store will consist of Types, Actions, Reducer and may be Selector.

In the beginning, let’s define types that will be used later:

11. An action, is an object that contains the payload of information.

Actions are the only source of information for the Redux store to be updated. They are the only things that trigger changes in a Redux application, they contain the payload for changes to an application store. Reducers update store based on the value of the action.type

12. A Reducer is a pure function that takes the state of an application and action as arguments and returns a new state. But not mutating the previous state.

Pure functions are functions that do not have any side effects and will return the same results if the same arguments are passed in.

Reducer need the initial state of an application in case of default state or null.

So we define the reducer part that aggregate this call by type GET_SUCCESS.

13. Redux-Saga has a reference to our store and it calls get state, passing the state into our selector. Now it is the time to write a React component to get data and show markers on map. Our task has been finished.

14. Addition to Reducer. In case of big implementation logic, we can move it out to the Selector. It makes our reducer small and readable. Let’s imagine we need to filter some data:

II. Additional ideas. Some objects behavior in React Native.

  1. Singleton in React: sometimes very useful to run function just once:

const useSingleton = (initializer) => {
React.useState(initializer);
}
const MyFunctionalComponent = () => {
useSingleton(() => {
// run only once
});
}

2. FC - Functional component

FC is a stateless component and doesn’t have the component lifecycle. Therefore you can’t specify a constructor.

You have to extend React.Component to create a stateful component which then will need a constructor and you'll be able to use the state.

Stateless:

import React from 'react'

To simulate constructor in FC use useEffect.

useEffect(() => {
// call some useful functions
}, []);

useEffect hook combined together old React lifecycle methods componentDidMount, componentDidUpdate, and componentWillUnmount.

3. How to notify the component if the variable has been changed?

const myList: MyDataSource[] = [];
useEffect(() => {
console.log(‘value has been changed’);
if (myList?.data) treatData(myList.data);
}, [myList]); //it is a way to use it to only re-run if variable changes

Careful with useEffect without depedency Array. By default, useEffect always runs after render has run. This means if you don’t include a dependency array, and you’re using useEffect you could end in a infinite loop. At least use empty array [].

Sometimes, array data not always updated, we can use this trick:

Instead of using data in the second argument array of useEffect(), we can also use [JSON.stringify(data)]:

useEffect(() => {
console.log(‘value has been changed’);
}, [JSON.stringify(data)]); // Changes will be caught :) !

4. Tricky part to handle map markers behavior. Marker state could be active or inactive. Let’s change the color to distinguish click on the map.

Conclusion

React Native provides another opportunity to create mobile application instead of using Flutter, Ionic, Android Java/Kotlin or iOS Swift. Redux split logic to types, actions, reducer and selector to make code more clear and testable for unit tests. Redux-Saga run implementation logic as background process.

Dev Genius

Coding, Tutorials, News, UX, UI and much more related to development

Sign up for Best Stories

By Dev Genius

The best stories sent monthly to your email. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Dev Genius

Coding, Tutorials, News, UX, UI and much more related to development

Aleksei Jegorov

Written by

Java, Kotlin, T-SQL, ASP.NET Core C#, Angular2, ReactJs, Android Java native developer in Estonia, Tallinn. https://github.com/wider2?tab=repositories

Dev Genius

Coding, Tutorials, News, UX, UI and much more related to development

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store