Hello Readers, CoolMonkTechie heartily welcomes you in this article ( How To Apply Run Time Android Permission In React Native ).
In this article, we will learn how to apply Run Time Android Permission In React Native. Android Permission feature helps a user to know which application is trying to access sensitive data such as files, contacts and SMS, and system-specific features such as camera and internet. This article shows to apply the run time permission with the authentic example.
To understand the Run Time Android Permission In React Native, we cover the below topics as below :
What is Android Permission?
Why we need permission?
How to apply Permission in Android?
How to apply run time Permission in React Native?
Example to apply the run time permission.
A famous quote about learning is :
” The great aim of education is not knowledge, but action. “
So Let’s begin.
What is Android Permission ?
According to Google’s privacy policy, a user should know which application is trying to access sensitive data such as files, contacts and SMS, and system-specific features such as camera and internet. So they introduced the Android Permission feature.
In Android permission modal, every application which is using sensitive data or some certain system features has to ask the permissions from the user.
The purpose of permission is to protect the privacy of an Android user.
Why We need Permission ?
Android applies the permission modal because some applications were tracking the user’s location in the background and accessing the private data like contacts, call history and messages without informing the user which is the violation of googles privacy policy.
So solving this sensitive issue application has to ask for permission to access those sensitive data.
How to Apply Permission in Android ?
Now we get an idea about the Android permission, let’s see how to apply the permission in Android.
To apply permission in Android, we have to follow two steps:
We have to add those permissions requests in project -> app -> src -> AndroidManifest.xml file.
For Example, if we want to ask for the device location Permission, we have to add the following permission request in AndroidManifest.xml :
After adding the permission in AndroidManifest file, this permission will be automatically asked by the play store when they install the app and this permission will be granted to the applications.
On devices before SDK version 23, the permissions are automatically granted if we add those permissions in our AndroidManifest.xml file, but after SDK version 23 we have to ask runtime permission as well.
2. After Google’s new permission modal, they have introduced the run time permission mechanism in Android version 23. According to that, we have to include all the permissions in AndroidManifest.xml and also have to apply some dangerouspermissions in run time.
According to the official docs, dangerouspermissions require a dialog prompt.
So whenever we are working with this dangerouspermissions, we need to check whether the permission is granted by the user, and that can be done with the help of PermissionsAndroid in React Native.
For example, If we need INTERNET permission and CAMERA permission then we have to add both the permission in AndroidManifest.xml file but have to ask only for the CAMERA permission in run time because CAMERA permission comes under the dangerous permission not INTERNET permission.
Run Time Permissions that requires Confirmation from the User. Here is the list of dangerous permissions.
READ_CALENDAR
android.permission.READ_CALENDAR
WRITE_CALENDAR
android.permission.WRITE_CALENDAR
CAMERA
android.permission.CAMERA
READ_CONTACTS
android.permission.READ_CONTACTS
WRITE_CONTACTS
android.permission.WRITE_CONTACTS
GET_ACCOUNTS
android.permission.GET_ACCOUNTS
ACCESS_FINE_LOCATION
android.permission.ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
android.permission.ACCESS_COARSE_LOCATION
RECORD_AUDIO
android.permission.RECORD_AUDIO
READ_PHONE_STATE
android.permission.READ_PHONE_STATE
CALL_PHONE
android.permission.CALL_PHONE
READ_CALL_LOG
android.permission.READ_CALL_LOG
WRITE_CALL_LOG
android.permission.WRITE_CALL_LOG
ADD_VOICEMAIL
com.android.voicemail
USE_SIP
android.permission.USE_SIP
PROCESS_OUTGOING_CALLS
android.permission.PROCESS_OUTGOING_CALLS
BODY_SENSORS
android.permission.BODY_SENSORS
SEND_SMS
android.permission.SEND_SMS
RECEIVE_SMS
android.permission.RECEIVE_SMS
READ_SMS
android.permission.READ_SMS
RECEIVE_WAP_PUSH
android.permission.RECEIVE_WAP_PUSH
RECEIVE_MMS
android.permission.RECEIVE_MMS
READ_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE
Run Time Permissions
How to apply Run Time Android Permission using React Native PermissionsAndroid ?
In React Native, PermissionsAndroid component provides access to Android M’s (Over API level 23) new permissions model. We always need to check the permission before using native APIs which comes under dangerous permissions.
Above mentioned all the dangerous permissions comes under PermissionsAndroid.PERMISSIONS as constants.
We can check the permission granted or not using PermissionsAndroid.RESULTS.GRANTED.
Permission denied by the user with never ask again.
Result Strings for Requesting Permissions
Now we get an idea about Android permissions and components. Let’s move towards the Example which can help us apply permission in our application.
Example to Apply the Run Time Permission
In this example, we will apply the device location permission, which needs run time permission. We are making a button on the centre of the screen and on a click of button we will apply the run time permission for device location known as ACCESS_FINE_LOCATION. So let’s get started.
Example Project Setup
To demonstration of apply the Run Time Permission, we have to follow the below steps:
Create a new React Native project
Adding device location permission in AndroidManifest.xml
1. Create a new React Native project
Assuming that we have node installed, we can use npm to install the react-native-clicommand line utility. Open the terminal and go to the workspace and run the following commands to create a new React Native project.
npx react-native init ProjectName
This will make a project structure with an index file named App.js in our project directory.
2. Adding device location permission in AndroidManifest.xml
If we are using any features in our app that needs permission, we need to add it in AndroidManifest.xml. For this example, we are adding device location permission in AndroidManifest.xml.
Here PermissionsAndroid.request has two arguments:
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION to generate a dialog to ask for Device Location Permission.
A JSON {‘title’:”,’message’:”}, which will help us to communicate or to show the dialog about the permission if the user denied the permission. They will generate it like this.
To Run the React Native Example Code
Open the terminal again, and jump into our project using
cd ProjectName
To run the project on an Android Virtual Device or on real debugging device
npx react-native run-android
or on the iOS Simulator by running (macOS only)
npx react-native run-ios (macOS only).
The output of example code is as below:
That’s all about in this article.
Conclusion
In this article, we understood how to apply Run Time Android Permission in React Native. This article showed the example code to apply the RunTime Android Permission in React Native.
Thanks for reading! I hope you enjoyed and learned about RunTime Android Permission Concepts in React Native. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
You can find Other articles of CoolmonkTechie as below link :
Hello Readers, CoolMonkTechie heartily welcomes you in this article (The most popular best ways to make REST API Calls in React Native ).
In this article, we will learn about different best ways to make REST API Calls in React Native. Many mobile apps need to load resources from a remote URL. We may want to make a POST request to a REST API, or we may need to fetch a chunk of static content from another server.
Applications on the web and mobile devices often cannot store all the information that they need. Therefore, they have to reach out to the web to update data, retrieve data, or request a service from a third-party. The transaction that takes place between two devices (client and server) is called an API call. An API (application programming interface) typically will use the REST design paradigm to manage all how it can be accessed (called).
This article shows the fetch function and the axios library. Both methods achieve the same task, making an HTTP call, but they go about it in slightly different ways.
A famous quote about learning is :
” The expert in anything was once a beginner. “
So Let’s begin.
Using Fetch
React Native provides the Fetch API for our networking needs. Fetch will seem familiar if we have used XMLHttpRequest or other networking APIs before. The Fetch API is a built-in Javascript function. We can use fetch by providing the URL for the location of our content. This will send a GET request to that URL.
Making Requests
In order to fetch content from an arbitrary URL, we can pass the URL to fetch:
fetch('https://mywebsite.com/mydata.json');
Fetch also takes an optional second argument that allows us to customize the HTTP request. We may want to specify additional headers, or make a POST request:
The above examples show how we can make a request. Most times, we will want to do something with the response.
Networking is an inherently asynchronous operation. Fetch methods will return a Promise that makes it straightforward to write code that works asynchronously:
By default, iOS will block any request that’s not encrypted using SSL. If we need to fetch from a cleartext URL (one that begins with http), then App Transport Security exception will first need to add.
It is more secure to add exceptions only for those domains, If we know ahead of time to need to access the domains; if we do not know the domains until runtime, ATS can completely disable.
This is a simple way to send HTTP requests as soon as possible. However, another popular method for sending HTTP requests is with third-party libraries.
Using XMLHttpRequest API
The XMLHttpRequest API is built into React Native. This means that we can use third-party libraries such as frisbee or axios that depend on it, or we can use the XMLHttpRequest API directly if we prefer.
var request = new XMLHttpRequest();
request.onreadystatechange = (e) => {
if (request.readyState !== 4) {
return;
}
if (request.status === 200) {
console.log('success', request.responseText);
} else {
console.warn('error');
}
};
request.open('GET', 'https://mywebsite.com/endpoint/');
request.send();
The security model for XMLHttpRequest differs from on web, as there is no concept of CORS in native apps.
Using WebSocket Protocal
React Native also supports WebSockets , a protocol which provides full-duplex communication channels over a single TCP connection.
var ws = new WebSocket('ws://host.com/path');
ws.onopen = () => {
// connection opened
ws.send('something'); // send a message
};
ws.onmessage = (e) => {
// a message was received
console.log(e.data);
};
ws.onerror = (e) => {
// an error occurred
console.log(e.message);
};
ws.onclose = (e) => {
// connection closed
console.log(e.code, e.reason);
};
Using Axios Library
The Axios is a Javascript library used to make HTTP requests, and it supports the Promise API that is native to JS ES6. The Axios library has grown in popularity alongside the increase in apps that exchange information using JSON. Three things that make the Axios library so useful are the ability to;
Intercept requests and responses
Transform request and response data
Automatically transform data for JSON
Axios Library Example
import Axios from 'axios'
Axios({
url: '/data',
method: 'get',
baseURL: 'https://example.com',
transformRequest: [function (data, headers) {
// Do whatever you want to transform the data
return data;
}],
transformResponse: [function (data) {
// Do whatever you want to transform the data
return data;
}],
headers: {'X-Requested-With': 'XMLHttpRequest'},
data: {
name: 'Some Name'
},
})
In the above example, we have passed a configuration object that calls an example URL with a GET request. We’ll notice that some parameter names are common between fetch and Axios.
We are calling the same URL as we did with the fetch API, but we don’t have to manually transform the response object into JSON. Axios has more features that can be useful with bigger applications.
That’s all about in this article.
Conclusion
In this article, we understood about different best ways to make REST API Calls in React Native. This article showed the fetch and axios library usage with code snippets in React Native .
Thanks for reading! I hope you enjoyed and learned about REST API Calls concepts in React Native. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
You can find Other articles of CoolmonkTechie as below link :
Hello Readers, CoolMonkTechie heartily welcomes you in this article.
In this article, we will learn how to use Redux with React Hooks by building a real React Native Application. Redux is a popular React and React Native state management library, meant to be used in complex React and React Native apps where sharing state between multi-level components can get extremely difficult to manage. React Hooks provide us the ability to use functional components in React or React Native apps. Their ability to provide support to manage a component’s state and handle side-effects offers an alternative to class components.
In this article, let us look at some hooks provided by the react-redux library that provides a way to avoid writing boilerplate code when using the connect() High Order Component.
To understand the use of Redux with React Hooks in React Native application, We will cover the below steps as below :
Configure a New React Native Application
Create Mock Screens
Set Up a Stack Navigator
Create an Overlay Modal With Transparent Background
Navigate to the Modal Screen
Add a Custom Modal With a Transparent Background
Adding a Text Input in the Custom Modal Screen
Add a Custom Header to the List Screen
Change the StatusBar Appearance
Add a List view
Creating a Root Reducer
Configuring a Store
Implement the useSelector Hook
Adding Items to the List by Dispatching an Action Creator
Adding FlatList to Display the Items in the List
Updating the Header
Removing an Item
The final code of the demo application
The final output of the demo application
A famous quote about learning is :
” The purpose of learning is growth, and our minds, unlike our bodies, can continue growing as we continue to live. “
So Let’s begin.
Step 1 – Configure a New React Native Application
To configure a new React Native app, we are going to use expo-cli with a blank template to generate a new app.
expo init projectname
Firstly, we have generated the project, Then we navigate inside the directory and install the following dependencies.
We are going to use Stack Navigator from the react-navigation library for two different screens in this demo app. For expo-cli, we run the following command to install required dependencies for the navigator to work.
In this section, let us create two screens that the app is going to use to display a list of items and allow the user to add to each item. We create a new directory called src/screens and then create two new ListScreen.js and ModalScreen.js files.
Each of these screen files is going to have some random data to display until the stack navigator is set up.
A Stack Navigator allows the app to transit between different or multiple screens and manages the navigation history. We create a new file called AppNavigator.js inside the src/navigation directory. This file is going to contain all the configurations required to set up a Stack Navigator.
With the recent release of react-navigationversion 5, the way to configure a stack navigator has changed. The major highlight of these new changes is the component-based configuration. Navigation patterns are now more component-based, common use cases can now be handled with pre-defined Hooks, the new architecture allowing us to configure and update a screen from within the component itself.
import * as React from "react";import { NavigationContainer } from "@react-navigation/native";import { createStackNavigator } from "@react-navigation/stack";import ListScreen from "../screens/ListScreen";import ModalScreen from "../screens/ModalScreen";
The NavigationContainer is a component provided by the react-navigation library that manages the navigation tree. It contains the navigation state and wraps all the navigator’s structure.
The createStackNavigator is a function that implements a stack navigation pattern. This function returns two React components: Screen and Navigator, that are going to allow us to configure each component screen.
Open the App.js file and import the MainStackNavigator in the root of the app as shown below:
import React from "react";import MainStackNavigator from "./src/navigation/AppNavigator";export default function App() {return <MainStackNavigator />;}
Now, we go the terminal window and execute the command expo start. In the simulator or the real device we are running the Expo client, we are going to notice similar results as shown below:
The first screen in the Stack Navigator is ListScreen, which is shown as above.
Step 4 – Create an Overlay Modal With Transparent Background
The modal can be easily configured with a stack navigator with an overlay of transparent background on the screen as they display it. Since the ListScreen is going to be the first screen and display a list of items, the ModalScreen is going to be a dialog. This dialog appears by clicking a button from the ListScreen in the current application and adds a transparent layer on the screen behind it when opened. The previous screen will be visible underneath this dialog.
This can be done by configuring screenOptions on a Stack Navigator. The react-navigation library provides a way to enable the overlay with a property called cardOverlayEnabled.
We have to configure the styles of both the screens and add a way for the modal dialog to open from the ListScreen.
Step 5 – Navigate to the Modal Screen
To navigate to the modal screen, let’s add a floating action button with an icon to the ListScreen.js screen component.
This button is going to be touchable and on a single touch is going to navigate to the ModalScreen. The navigation is going to be handled by the navigation prop that can be passed as an argument to the functional component ListScreen. This is only possible because the ListScreen is part of the Stack navigator.
Any screen in a React Native app that utilizes a react-navigation library is a route or a part of a navigation pattern that has access to navigation prop.
We go back to the simulator device, and we are going to notice the changes. The first thing to notice is the action button floating at the bottom right corner.
On pressing this button, a full-screen modal will open.
Step 6 – Add a Custom Modal With a Transparent Background
In this section, let’s change the behavior of how the modal appears on the ListScreen right now and how we want it to be. As an overlay, we also want it to take the only 1/3rd of the current screen.
This modal is going to have an input field in the future to let the user add items to the list. However, for now, it is going to display a text and a close button.
The close button is going to dismiss the modal when the user wants to go back to the List screen without taking any other action. The close button is going to be placed using position:absolute property and is going to use navigation.goBack() pre-defined method to go back to the List screen.
Here is the complete code for the modal screen at this point. Open ModalScreen.js and modify it.
Here is the output you are going to get in the device after this step:
Step 7 – Adding a Text Input in the Custom Modal Screen
In this section, let’s add a text input component from the react-native core. This is going to allow the user to enter the name of the item they want to add to the list. For now, since we haven’t configured the Redux to manage the app state, let us use the hook useState to manage the component state locally.
Open ModalScreen.js and import TextInput from react-native core.
import {StyleSheet,TouchableOpacity,Text,View,TextInput,} from "react-native";
Next, inside the View that has the style of modalContainer add the following TextInput component as well as a touchable submit button. This touchable button is going to navigate back to the list screen when the user has entered a value in the input field.
Create a new file called Header.js inside the directory src/components. This functional component is going to display the header title in the List screen.
Add the following code snippet to the file. We have just created:
We will now notice that the Status bar has a white appearance.
Step 10 –Add a List view
In this section, let’s implement the main view that is going to display a list of items. In ListScreen.js, add the following functional component called ListView.
function ListView() {return (<Viewstyle={{backgroundColor: "white",flex: 1,borderTopLeftRadius: 20,borderTopRightRadius: 20,paddingHorizontal: 20,paddingVertical: 20,}}><Text>Here goes list items</Text></View>);}
Then, modify the ListScreen to display it below the Header.
<View style={styles.container}><Header title={"List"} /><ListView />{/* rest of the code remains same */}</View>;
Go to the device, we are running the app, and we are going to notice a major difference in its appearance.
Step 11 –Creating a Root Reducer
In this section, we create a new directory called src/redux/ and inside it, a new file called reducer.js. This file is going to have the definition of action types, action creators and the only reducer we are going to create in this app. This reducer is going to be called rootReducer.
Redux is used to manage the state of the whole application. Therefore, it represents this state by one JavaScript object. Think of this object as read-only (immutable), since we cannot change this state or the object because they represent it in the form of a tree. It requires an action to do so.
Actions are similar to events in Redux. And, they can be triggered in the button press, timers or network requests.
Start by defining an action type as below.
export const ADD_ITEM = 'ADD_ITEM'
Then we define the action creator called addItem that is going to take an item from the user’s input and add it to the list. This is the action creator function that we are going to trigger later.
Define an initial state which is going to have an empty array called itemList. Whenever an action is triggered, the state of the application changes. The handling of the application’s state is done by the reducers.
This initial state is going to be passed as a parameter to the rootReducer. Calling the create action is going to invoke the logic defined for the same action type in the reducer.
Using a reducer, we either want to initiate the current app state or update it, without modifying the whole state on each action trigger. The spread operator returned in the action type ADD_ITEM indicates that.
To update the state, in our case, to add an item object to the itemList array, let us use the contact() that is going to return a new array whenever an item is added to the list. This also satisfies the redux philosophy of not mutating the state directly.
In this section, we create a new file src/redux/store.js. A store is an object that brings the actions and reducers together. This file is going to implement that.
The store provides and holds the state at the application level instead of individual components. Add the following code snippet to it:
import { createStore } from "redux";import rootReducer from "./reducer";const store = createStore(rootReducer);export default store;
Now, we connect this store to the app, we open App.js file and import the store from this file as well as the High Order Component Provider from react-redux npm package. This HOC helps us to pass the store down to the rest of the components of the current app.
import React from "react";import { Provider as StateProvider } from "react-redux";import store from "./src/redux/store";import MainStackNavigator from "./src/navigation/AppNavigator";export default function App() {return (<StateProvider store={store}><MainStackNavigator /></StateProvider>);}
Step 13 – Implement the useSelector Hook
To access state when managing it with Redux, the useSelector hook is provided in the library. It is similar to mapStateToProps argument that is passed inside the connect(). It allows us to extract data from the Redux store state using a selector function.
The major difference between the hook and the argument (the older way) is that the hook may return any value as a result, not just an object.
Inside ListScreen.js add the following import statement.
import { useSelector } from 'react-redux'
Then, we fetch the listItems array using the hook useSelector inside the ListView component. Also, modify its return statement by displaying a message if the list is empty or not.
function ListView() {const listItems = useSelector((state) => state.itemList);return (<Viewstyle={{backgroundColor: "white",flex: 1,borderTopLeftRadius: 20,borderTopRightRadius: 20,paddingHorizontal: 20,paddingVertical: 20,}}>{listItems.length !== 0 ? (<Text>Contains List items</Text>) : (<Text style={{ fontSize: 30 }}>You list is empty :'(</Text>)}</View>);}
Step 14 –Adding Items to the List by Dispatching an Action Creator
The useDispatch() hook completely refers to the dispatch function from the Redux store. This hook is used only when there is a need to dispatch an action. In the ModalScreen.js to add an item based on the value of TextInput, the state has to be updated. This can be done by triggering the action creator method called addItemdefined when creating actions inside redux/reducer.js file.
Start by importing the following statements:
import { useDispatch } from 'react-redux'import { addItem } from '../redux/reducer'
Next, inside the ModalScreencomponent, we create a helper method called onSaveNote which when triggered on submission of the text input, is going to trigger the action creator as well as take the user back to the List screen.
function ModalScreen({ navigation }) {const [value, setValue] = useState("");const dispatch = useDispatch();const onSaveNote = (value) => {dispatch(addItem(value));navigation.navigate("List");};/* rest of the code remains same */}
Lastly, add this helper method as the value of onPress on the submission button.
In this section, using the current app’s state, let us display the number of items in the list to be shown in the header as well. This can be done by using useSelector hook from react-redux.
Modify the file components/Header.js as the following:
Here is the updated header bar when there is one item on the list.
Step 17 –Removing an Item
Since we have gone through the process of understanding how redux hooks work with React Native apps, we try adding a remove item button that is going to delete an item from the list as shown below.
Here is the updated redux/reducer file that has action type REMOVE_ITEM.
import React from "react";import { Provider as StateProvider } from "react-redux";import store from "./src/redux/store";import MainStackNavigator from "./src/navigation/AppNavigator";export default function App() {return (<StateProvider store={store}><MainStackNavigator /></StateProvider>);}
19. The final output of the demo application
Here is the final output of the demo app:
That’s all about in this article.
Conclusion
In this article, we understood how to use Redux with React Hooks by building a real React Native application. This article showed the demo code step by step to use Redux with React Hooks by building a real React Native application. The addition to hooks in react-redux such as useSelector and useDispatch reduces the need to write plentiful boilerplate code and also provides the advantage to use functional components. We also discussed better understanding of the basics of react navigation in real React native application.
Thanks for reading! I hope you enjoyed and learned about Redux and React Hooks practical usage in React Native application. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
You can find Other articles of CoolmonkTechie as below link :
Hello Readers, CoolMonkTechie heartily welcomes you in this article (How To Handle Deep Linking in React Native ?).
In this article, We will learn how to handle deep linking in react native. Mobile apps have a unique vulnerability that is non-existent in the web: Deep Linking. Deep Linking is a technique in which a given URL or resource is used to open a specific page or screen on mobile. So, instead of just launching the app on mobile, a deep link can lead a user to a specific page within the app, providing a better experience. This specific page or screen may reside under a series of hierarchical pages, hence the term “deep” in deep linking.
Deep linking is a way of sending data directly to a native application from an outside source. A deep link looks like app:// where app is our app scheme and anything following the // could be used internally to handle the request. As a user, we probably have experienced deep linking when opening a link to a product in a browser. If we have the app of that shop installed, it may use a deep link to open the app on that product’s page.
For example, if we were building an e-commerce app, we could use app://products/1 to deep link to our app and open the product detail page for a product with id 1. We can think of these kind of like URLs on the web.
” Deep linking consists of using a uniform resource identifier (URI) that links to a specific location within a mobile app rather than simply launching the app. Deferred deep linking allows users to deep link to content even if the app is not already installed. “
In this article, we will discuss a React Native app that opens a specific page based on the URI provided from an external source.
A famous quote about learning is :
” The beautiful thing about learning is nobody can take it away from you. “
So Let’s begin.
Why Deep Linking?
Deep Link has many use cases where it can come very handy. Think of marketing strategies, referral links, sharing a certain product, etc. The greatest benefit of mobile deep linking is the ability for marketers and app developers to bring users directly into the specific location within their app with a dedicated link. Just as deep links made the web more usable, mobile deep links do the same for mobile apps.
Example
Let’s try to mimic a React Native demo app that opens a specific page based on the URI provided from an external source. To handle deep links, we are going to use an optimum solution provided by the react-navigation library.
Configure react-navigation in a React Native App
To start, we create a new React Native project by running the following command:
react-native init rnDeepLinkingDemo
cd rnDeepLinkingDemo
To be able to support deep linking via the navigation, we add the required npm dependencies. Once the project directory has been generated from the above command, navigate inside the project folder from our terminal and install the following dependencies.
The next step is to link all the libraries we just installed. From React Native 0.60 and higher, linking is automatic. So we don’t need to runreact-native link.
On iOS devices, we just have to run the following set of commands.
cd ios
pod install
cd ..
For Android devices, we add the following lines to the android/app/build.gradle file under the dependencies section:
Then, open the android/app/src/main/java/com/rndeeplinkdemo/MainActivity.java file and add the following snippet:
package com.rndeeplinkingdemo;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "RNDeepLinkingDemo";
}
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
}
Create a Home & Details Screen
We are going to create all the screens for this example inside the directory src/screens. To start with the home screen, create a new file Home.js inside the aforementioned path.
This screen is going to render a list of users from an array of mock data from a placeholder API using a FlatList component. Each user is going to be wrapped inside a TouchableOpacity. The reason being, when an end-user presses a username from the list, this is going to contain the logic for navigating from the Home screen to the Details screen (which we will add later).
For the details screen, for now, let us display user list details. We create a new file called Details.js. To display information for each user when visiting the Details screen, we have to pass the value of each item using navigation parameters. Next, To fetch the data from the placeholder API on initial render, let us use the useEffect hook from React. This hook is going to behave like a good old lifecycle method componentDidMount(). It also allows that if the full item object is passed or not. If not, just grab the userId and request the API. Then, define a state variable data to store the incoming user information. Also, modify the contents of return in this component screen.
To navigate from Home to Details screen, we need Stack Navigator from react-navigation. We create a new file called index.js inside the src/navigation directory and import the following statements.
import React from 'react'
import { createAppContainer, createSwitchNavigator } from 'react-navigation'
import { createStackNavigator } from 'react-navigation-stack'
import Home from '../screens/Home'
import Details from '../screens/Details'
Create a stack navigator with Home as the initial screen. To enable deep linking, the current app requires an identifier to recognize the URI path from the external source to the screen of the app. The library react-navigation provides a path attribute for this. It tells the router relative path to match against the URL. We configure both the routes as follows:
In the above snippet, the dynamic variable specified by :userId is passed to details/. This is going to allow the app to accept a dynamic value such as details/1234.
Next, we add the configuration to the navigation to extract the path from the incoming URL from the external resource. This is done by uriPrefix. Add the following code snippet at the end of the file:
To make this work, we have to configure the native iOS and Android app to open URLs based on the prefix myapp://.
For iOS devices, open the ios/rnDeepLinkDemo/AppDelegate.m file and add the following.
// Add the header at the top of the file:
#import <React/RCTLinkingManager.h>
// Add this above the `@end`:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:app openURL:url options:options];
}
Open ios/rnDeepLinkingDemo.xcodeproj in the Xcode app and select the app from the left navigation bar.
Open the Info tab.
Next, go to the URL Types.
Click the + button and in identifier as well as URL schemes add myapp.
Rebuild the React Native binaries by running react-native run-ios.
For Android users, we have to configure the external linking as well. Open /android/app/src/main/AndroidManifest.xml and set the value of launchMode to singleTask. Also, add a new intent-filter:
Let’s understand the intent-filter a little better.
” An intent filter is an expression in an app’s manifest file that specifies the type of intents that the component would like to receive.“
Get a closer look on <data> tag inside <intent-filter>. There are two properties that we have to care about. Consider scheme as a type of incoming link and host as the URL.
” Our Deep Link will look something like this: myapp://home .
Testing The App
Before we run the app on our platform of choice, make sure to re-build it using the specific command for the mobile OS as below:
To test deep link in iOS, we open a web browser in our iOS simulator device and run the URL myapp://home. It is going to ask us to whether open the external URI in the app . Next, try entering the URL myapp://details/1 and see what happens.
To test deep link in Android, we make sure our android app is in background and run this command:
adb shell am start -W -a android.intent.action.VIEW -d myapp://home com.rndeeplinkingdemo
adb shell am start -W -a android.intent.action.VIEW -d myapp://details/1 com.rndeeplinkingdemo
If our package has a different name then edit command as follows:
$ adb shell am start -W -a android.intent.action.VIEW -d <URI> <PACKAGE>
If our App opened successfully then our Deep Linking is working as expected.
That’s all about in this article.
Conclusion
In this article, We understood how to handle Deep Linking in React Native. We also discussed about a complete demo of a React Native app that handles deep linking using react-navigation. Deep linking can bring significant improvements to the user experience of our mobile apps and enable search engines to provide context-sensitive searches and results.
Thanks for reading ! I hope you enjoyed and learned about the Deep Linking Concepts in React Native. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
You can find Other articles of CoolmonkTechie as below link :
Hello Readers, CoolMonkTechie heartily welcomes you in this article (How To Manage The Lifecycle of Gestures In React Native ?).
In this article, We will learn how to manage the lifecycle of gestures in react native. The gesture responder system manages the lifecycle of gestures in react native application. A touch can go through several phases as the app determines what the user’s intention is. For example, the app needs to determine if the touch is scrolling, sliding on a widget, or tapping. This can even change during the duration of a touch. There can also be multiple simultaneous touches.
The touch responder system is needed to allow components to negotiate these touch interactions without any additional knowledge about their parent or child components.
A famous quote about learning is :
” Change is the end result of all true learning. “
So Let’s begin.
Best Practices
To make our app feel great, every action should have the following attributes:
Feedback/highlighting – show the user what is handling their touch, and what will happen when they release the gesture
Cancel-ability – when making an action, the user should be able to abort it mid-touch by dragging their finger away
These features make users more comfortable while using an app, because it allows people to experiment and interact without fear of making mistakes.
TouchableHighlight and Touchable
The responder system can be complicated to use. So we have provided an abstract Touchable implementation for things that should be “tappable“. This uses the responder system and allows us to configure tap interactions declaratively. Use TouchableHighlight anywhere where we would use a button or link on web.
Gesture Responder System Lifecycle
A view can become the touch responder by implementing the correct negotiation methods. There are two methods to ask the view if it wants to become responder:
View.props.onStartShouldSetResponder: (evt) => true, – Does this view want to become responder on the start of a touch?
View.props.onMoveShouldSetResponder: (evt) => true, – Called for every touch move on the View when it is not the responder: does this view want to “claim” touch responsiveness?
If the View returns true and attempts to become the responder, one of the following will happen:
View.props.onResponderGrant: (evt) => {} – The View is now responding for touch events. This is the time to highlight and show the user what is happening.
View.props.onResponderReject: (evt) => {} – Something else is the responder right now and will not release it.
If the view is responding, the following handlers can be called:
View.props.onResponderMove: (evt) => {} – The user is moving their finger.
View.props.onResponderRelease: (evt) => {} – Fired at the end of the touch, ie “touchUp”.
View.props.onResponderTerminationRequest: (evt) => true – Something else wants to become responder. Should this view release the responder? Returning true allows release.
View.props.onResponderTerminate: (evt) => {} – The responder has been taken from the View. Might be taken by other views after a call to onResponderTerminationRequest, or might be taken by the OS without asking (happens with control center/ notification center on iOS).
evt is a synthetic touch event with the following nativeEvent form:
changedTouches – Array of all touch events that have changed since the last event
identifier – The ID of the touch
locationX – The X position of the touch, relative to the element
locationY – The Y position of the touch, relative to the element
pageX – The X position of the touch, relative to the root element
pageY – The Y position of the touch, relative to the root element
target – The node id of the element receiving the touch event
timestamp – A time identifier for the touch, useful for velocity calculation
touches – Array of all current touches on the screen
Capture ShouldSet Handlers
onStartShouldSetResponderand onMoveShouldSetResponder are called with a bubbling pattern, where the deepest node is called first. That means that the deepest component will become responder when multiple Views return true for ShouldSetResponderhandlers. This is desirable in most cases, because it makes sure all controls and buttons are usable.
However, sometimes a parent will want to make sure that it becomes responder. This can be handled by using the capture phase. Before the responder system bubbles up from the deepest component, it will do a capture phase, firing on ShouldSetResponderCapture. So if a parent View wants to prevent the child from becoming responder on a touch start, it should have a onStartShouldSetResponderCapture handler which returns true.
PanResponder reconciles several touches into a single gesture. It makes single-touch gestures resilient to extra touches, and can be used to recognize basic multi-touch gestures.
By default, PanResponder holds an InteractionManager handle to block long-running JS events from interrupting active gestures.
It provides a predictable wrapper of the responder handlers provided by the gesture responder system. For each handler, it provides a new gestureState object alongside the native event object:
onPanResponderMove: (event, gestureState) => {}
A native event is a synthetic touch event with form of PressEvent.
A gestureState object has the following:
stateID – ID of the gestureState- persisted as long as there at least one touch on screen
moveX – the latest screen coordinates of the recently-moved touch
moveY – the latest screen coordinates of the recently-moved touch
x0 – the screen coordinates of the responder grant
y0 – the screen coordinates of the responder grant
dx – accumulated distance of the gesture since the touch started
dy – accumulated distance of the gesture since the touch started
vx – current velocity of the gesture
vy – current velocity of the gesture
numberActiveTouches – Number of touches currently on screen
API
Only a single component can respond to touch events at one time – the component responding to events owns a global “interaction lock”. The PanResponder API helps us manage what component owns this lock through a set of callbacks. Each of these callbacks is also passed an event and gestureStateobject containing info about the touch events (e.g. position and velocity).
To create a PanResponder, we call PanResponder.create(callbacksObject). The result is a set of props that can be passed to View as props (these are the lower-level touch event handling props). We’ll typically wrap the result with useRef, since we only want to create a single PanResponder for the lifecycle of the component.
const ExampleComponent = () => {
const panResponder = React.useRef(
PanResponder.create({
// Ask to be the responder:
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) =>
true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) =>
true,
onPanResponderGrant: (evt, gestureState) => {
// The gesture has started. Show visual feedback so the user knows
// what is happening!
// gestureState.d{x,y} will be set to zero now
},
onPanResponderMove: (evt, gestureState) => {
// The most recent move distance is gestureState.move{X,Y}
// The accumulated gesture distance since becoming responder is
// gestureState.d{x,y}
},
onPanResponderTerminationRequest: (evt, gestureState) =>
true,
onPanResponderRelease: (evt, gestureState) => {
// The user has released all touches while this view is the
// responder. This typically means a gesture has succeeded
},
onPanResponderTerminate: (evt, gestureState) => {
// Another component has become the responder, so this gesture
// should be cancelled
},
onShouldBlockNativeResponder: (evt, gestureState) => {
// Returns whether this component should block native components from becoming the JS
// responder. Returns true by default. Is currently only supported on android.
return true;
}
})
).current;
return <View {...panResponder.panHandlers} />;
};
Example
PanResponder works with Animated API to help build complex gestures in the UI. The following example contains an animated View component which can be dragged freely across the screen.
In this article, We understood how to manage the lifecycle of gestures in react native. We also discussed about Best Practices and PanResponser usage in React Native platform.
Thanks for reading ! I hope you enjoyed and learned about the Gestures Concepts in React Native. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
You can find Other articles of CoolmonkTechie as below link :
Hello Readers, CoolMonkTechie heartily welcomes you in this article (How To Navigate Between Screens In React Native ?).
In this article, We will learn how to navigate between screens in react native. Mobile apps are rarely made up of a single screen. Managing the presentation of, and transition between, multiple screens is typically handled by what is known as a navigator. This article covers the various navigation components available in React Native. If we are getting started with navigation, we will probably want to use React Navigation. React Navigation provides a straightforward navigation solution, with the ability to present common stack navigation and tabbed navigation patterns on both Android and iOS.
If we’d like to achieve a native look and feel on both Android and iOS, or we’re integrating React Native into an app that already manages navigation natively, the following library provides native navigation on both platforms: react-native-navigation.
A famous quote about learning is :
” Study hard what interests you the most in the most undisciplined, irreverent and original manner possible. “
So Let’s begin.
Overview
The community solution to navigation is a standalone library that allows developers to set up the screens of an app with a few lines of code.
React Navigation is the most popular navigation library. It handles most of the challenges described above nicely, and is sufficiently configurable for most apps.
React Navigation provides all the different type of navigator like
Stack Navigator : For the simple screen switching
Drawer Navigator : To create Navigation Drawer/ Sidebar
Bottom Tab Navigator : For the bottom navigation
Top Tab Navigator : To create the tab navigation
Navigation Challenges
There are a few aspects of navigation which make it challenging in React Native:
Navigation works differently on each native platform. iOS uses view controllers, while android uses activities. These platform-specific APIs work differently technically and appear differently to the user. React Native navigation libraries try to support the look-and-feel of each platform, while still providing a single consistent JavaScript API.
Native navigation APIs don’t correspond with “views”. React Native components like View, Text, and Image, roughly map to an underlying native “view”, but there isn’t really an equivalent for some of the navigation APIs. There isn’t always a clear way to expose these APIs to JavaScript.
Navigation on mobile is stateful. On the web, navigation is typically stateless, where a url (i.e. route) takes a user to a single screen/page. On mobile, the history of the user’s navigation state is persisted in the application so that the user can go back to previous screens – a stack of screens can even include the same screen multiple times.
Due to these challenges, there isn’t a single best way to implement navigation, so it was removed from the core React Native package.
Next, we install the required peer dependencies. We need to run different commands depending on whether our project is an Expo managed project or a bare React Native project.
If we have an Expo managed project, install the dependencies with expo:
For iOS with bare React Native project, make sure we have Cocoapods installed. Then we install the pods to complete the installation:
cd ios
pod install
cd ..
We might get warnings related to peer dependencies after installation. They are usually caused by incorrect version ranges specified in some packages. We can safely ignore most warnings as long as our app builds.
To finalize installation of react-native-gesture-handler, add the following at the top (make sure it’s at the top and there’s nothing else before it) of our entry file, such as index.js or App.js:
import 'react-native-gesture-handler';
Now, we need to wrap the whole app in NavigationContainer. Usually we’d do this in our entry file, such as index.js or App.js :
import 'react-native-gesture-handler';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
const App = () => {
return (
<NavigationContainer>
{/* Rest of app code */}
</NavigationContainer>
);
};
export default App;
Now we are ready to build and run our app on the device/simulator.
Steps For Adding React Navigation To The App
In this section, we’ll walk through adding react-navigation to an app.
After install the required dependencies, we need to do 3 things:
Set up a <NavigationContainer> from @react-navigation/native
Create a navigator:
createStackNavigator from @react-navigation/stack
createBottomTabNavigator from @react-navigation/bottom-tabs
createDrawerNavigator from @react-navigation/drawer
Define the screens in our app
1. Create a navigator
We first choose one of the available navigators, e.g. stack, which will act as our root navigator. Navigators may be nested later.
import { createStackNavigator } from '@react-navigation/stack'
const Root = createStackNavigator()
2. Create screen components
Next, we create a component for each screen.
Screens are regular React components. They’ll be passed navigation-specific props when instantiated.
Lastly, we render a NavigationContainer with our navigator within it.
Each Screen component defines a route in our app. If we want nested navigators, e.g. a tab navigator within a stack navigator, we can use another navigator as a screen’s component. We only need a single NavigationContainer, even if we have nested navigators.
For components which aren’t screens (direct descendants of a navigator), we can access the navigation and route objects using hooks. Some developers prefer using these hooks instead of props, even in screen components.
In this example, there are 2 screens (Home and Profile) defined using the Stack.Screen component. Similarly, we can define as many screens as we like.
We can set options such as the screen title for each screen in the options prop of Stack.Screen.
Each screen takes a component prop that is a React component. Those components receive a prop called navigation which has various methods to link to other screens. For example, we can use navigation.navigate to go to the Profile screen:
The views in the stack navigator use native components and the Animated library to deliver 60fps animations that are run on the native thread. Plus, the animations and gestures can be customized.
React Navigation also has packages for different kind of navigators such as tabs and drawer. We can use them to implement various patterns in our app.
That’s all about in this article.
Conclusion
In this article, We understood how to navigate between screens in react native. We also discussed about navigation challenges, dependencies and navigation usage in React Native platform.
Thanks for reading ! I hope you enjoyed and learned about the Navigation Concepts in React Native. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
You can find Other articles of CoolmonkTechie as below link :
Hello Readers, CoolMonkTechie heartily welcomes you in A Short Note Series (Functional vs Class Components in React Native).
In this note series, we will understand about the difference between Functional and Class Components in React Native.
So Let’s begin.
In React Native, there are two main types of components that make up an application: functional components and class components. These are structured the same as they would be in a regular React app for the web.
Class Components vs Functional Components
1. Syntax
Class components are JavaScript ES2015 classes that extend a base class from React called Component and create a render function that returns a React element. This requires more code as well.
In Class components, there is a way to store and manage state built in to React Native. This gives the class App access to the React life cycle methods like render as well as state/props functionality from the parent. While managing the state in classes, we use setState and this.state to set and get the state, respectively.
Another most important difference in Class and Functional Component is the life cycle methods, or we can say Lifecycle Hooks. We all know how important is the Lifecycle methods while developing any React Native application. Life cycle methods give us the power to control the data and application flow on different activities. We are very much familiar with the class component Lifecycle methods but in case of Functional Components we have to manage all this with the help of useEffect hook.
In this note series, we understood about the difference between Functional and Class Components in React Native. We conclude that :
Class components are used as container components to handle state management and wrap child components.
Functional components are just used for display purposes – these components call functions from parent components to handle user interactions or state updates.
Thanks for reading! I hope you enjoyed and learned about Functional Vs Class Components Concepts in React Native. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe to the blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
You can find Other articles of CoolmonkTechie as below link :
Hello Readers, CoolMonkTechie heartily welcomes you in this article.
In this article, we will talk about the ins and outs of Jest to help you get started with testing. we will learn more about the vocabulary associated with Jest testing, like mocks and spies. Also, we’ll cover some of the basics of Jest testing, like using describe blocks and the keywords it and expect. Finally, we’ll take a look at snapshot testing and why it’s particularly useful for front-end testing.
A famous quote about learning is :
” The more I live, the more I learn. The more I learn, the more I realizes, the less I know.“
So Let’s start.
What Is Jest?
Jest was created by Facebook specifically for testing React applications. It’s one of the most popular ways of testing React components. Since its introduction, the tool has gained a lot of popularity. This popularity has led to the use of Jest for testing both JavaScript front-end and back-end applications. Many large companies—including Twitter, Instagram, Pinterest, and Airbnb—use Jest for React testing.
Jest itself is actually not a library but a framework. There’s even a CLI tool that you can use from the command line. To give an example, the CLI tool allows you to run only specific tests that match a pattern. Besides that, it hosts much more functionality, which you can find in the CLI documentation.
Jest offers a test runner, assertion library, CLI tool, and great support for different mocking techniques. All of this makes it a framework and not just a library.
Jest Characteristics
From the JestJS.io website, we can find four main characteristics of Jest:
Zero config: “Jest aims to work out of the box, config free, on most JavaScript projects.” This means you can simply install Jest as a dependency for your project, and with no or minimal adjustments, you can start writing your first test.
Isolated: Isolation is a very important property when running tests. It ensures that different tests don’t influence each other’s results. For Jest, tests are executed in parallel, each running in their own process. This means they can’t interfere with other tests, and Jest acts as the orchestrator that collects the results from all the test processes.
Snapshots: Snapshots are a key feature for front-end testing because they allow you to verify the integrity of large objects. This means you don’t have to write large tests full of assertions to check if every property is present on an object and has the right type. You can simply create a snapshot and Jest will do the magic. Later, we’ll discuss in detail how snapshot testing works.
Rich API: Jest is known for having a rich API offering a lot of specific assertion types for very specific needs. Besides that, its great documentation should help you get started quickly.
Jest Vocabulary
Mock
From the Jest documentation, we can find the following description for a Jest mock:
“Mock functions make it easy to test the links between code by erasing the actual implementation of a function, capturing calls to the function (and the parameters passed in those calls).”
In addition, we can use a mock to return whatever we want it to return. This is very useful to test all the paths in our logic because we can control if a function returns a correct value, wrong value, or even throws an error.
In short, a mock can be created by assigning the following snippet of code to a function or dependency:
jest.fn()
Here’s an example of a simple mock, where we just check whether a mock has been called. We mock mockFn and call it. Thereafter, we check if the mock has been called:
A spy has a slightly different behavior but is still comparable with a mock. Again, from the official docs, we read,
“Creates a mock function similar to jest.fn() but also tracks calls to object[methodName]. Returns a Jest mock function.”
What this means is that the function acts as it normally would—however, all calls are being tracked. This allows you to verify if a function has been called the right number of times and held the right input parameters.
Below, you’ll find an example where we want to check if the play method of a video returns the correct result but also gets called with the right parameters. We spy on the play method of the video object. Next, we call the play method and check if the spy has been called and if the returned result is correct. Pretty straightforward! In the end, we must call the mockRestore method to reset a mock to its original implementation.
Let’s take a look at some basics on writing tests with Jest.
Describe Blocks
A describe block is used for organizing test cases in logical groups of tests. For example, we want to group all the tests for a specific class. We can further nest new describe blocks in an existing describe block. To continue with the example, you can add a describe block that encapsulates all the tests for a specific function of this class.
“It” or “Test“ Tests
We use the test keyword to start a new test case definition. The it keyword is an alias for the test keyword. Personally, I like to use it, which allows for more natural language flow of writing tests. For example:
Next, let’s look at the matchers Jest exposes. A matcher is used for creating assertions in combination with the expect keyword. We want to compare the output of our test with a value we expect the function to return.
Again, let’s look at a simple example where we want to check if an instance of a class is the correct class we expect. We place the test value in the expect keyword and call the exposed matcher function toBeInstanceOf(<class>) to compare the values. The test results in the following code:
it('should be instance of Car', () => {
expect(newTruck()).toBeInstanceOf(Car);
});
The complete list of exposed matchers can be found in the Jest API reference.
Snapshot Testing for React Front Ends
At last, the Jest documentation suggests using snapshot tests to detect UI changes. As I mentioned earlier, snapshot testing can also be applied for checking larger objects, or even the JSON response for API endpoints.
Let’s take a look at an example for React where we simply want to create a snapshot for a link object. The snapshot itself will be stored with the tests and should be committed alongside code changes.
If the link object changes, this test will fail in the future. If the changes to the UI elements are correct, you should update the snapshots by storing the results in the snapshot file. You can automatically update snapshots using the Jest CLI tool by adding a “-u” flag when executing the tests.
Conclusion
In this article, We understood about the Jest Framework Concepts . We learnt more about the vocabulary associated with Jest testing, like mocks and spies. Also, we have covered some of the basics of Jest testing, like using describe blocks and the keywords it and expect with snapshot testing and why it’s particularly useful for front-end testing.
Thanks for reading ! I hope you enjoyed and learned about the Jest unit testing framework concepts . Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.
Hello Readers, CoolMonkTechie heartily welcomes you in this article.
In this article, we will learn about Direct Manipulation in React Native. Direct manipulation is an important concept in react native.
To understand the direct manipulation concept, we will discuss the below topics :
What is Direct Manipulation ?
How Direct Manipulation Works ?
UseCase using setState and setNativeProps
A famous quote about learning is :
” We now accept the fact that learning is a lifelong process of keeping abreast of change. And the most pressing task is to teach people how to learn.”
So, Let’s begin.
What is Direct Manipulation ?
The definition of Direct Manipulation says that
” Direct Manipulation is the process of making a component changes directly without using state/props or render whole hierarchies of components for a small change in one component.“
Before the understanding of direct manipulation, we need to understand that how any components display on the UI Screen ?
The answer is that we need to write code for that components in render() method to display any component in the screen.
Now, what if you want to add/change any component?
The answer is we have to change state or props, otherwise the render() method will not be called. The render() method renders the whole component hierarchies even if there is a change in the only one component.
So the solution for this problem is Direct Manipulation that does not render all the component hierarchies for one component change.
In other way, we can say that
“It is sometimes necessary to make changes directly to a component without using state/props to trigger a re-render of the entire subtree (or render the whole hierarchies of components for a small change in one component). This process is called Direct Manipulation.“
How Direct Manipulation Works ?
In this section, we will see that how to work Direct Manipulation.
Direct Manipulation uses setNativeProps and Refs. setNativeProps is the react native equivalent to setting the properties directly on a DOM node.
and then, next question is “When to use setNativeProps and Refs ?”
Use setNativeProps when frequent re-rendering creates a performance bottleneck.
Direct manipulation will not be a tool that we reach for frequently; we will typically only be using it for creating continuous animations to avoid the overhead of rendering the component hierarchy and reconciling many views. setNativeProps is imperative and stores state in the native layer (DOM, UIView, etc.) and not within our React components, which makes our code more difficult to reason about. Before we use it, try to solve our problem with setState and shouldComponentUpdate.
UseCase
Let’s understand setNativeProps /Refs and setState concepts with one use case with the below code examples:
” We have one TextInput which should be cleared when button is pressed.“
In this above code example, we change the text or clear button each time. Render method is called which re-render the whole component even if there is a change for the component.
In above code example, render method will not be called when we click on clear text button or text is changed.
So Here the component will not be re-rendered. We can change any props of a component using setProps and Refs without using re-render().
Some times If we update a property that is also managed by the render function, we might end up with some unpredictable and confusing bugs because anytime the component re-renders and that property changes, whatever value was previously set from setNativeProps will be completely ignored and overridden. So we need to avoid conflict with the render function.
By intelligently applying shouldComponentUpdate, we can avoid the unnecessary overhead involved in reconciling unchanged component subtrees, to the point where it may be performant enough to use setState instead of setNativeProps.
That’s all about in this article.
Conclusion
In this article, We understood about Direct Manipulation in React Native. We also discussed how Direct Manipulation works with use-case. In Summary, we can say that :
Direct Manipulation is the process of making a component changes directly without using state/props.
Direct Manipulation helps to prevent render all the component hierarchies for one component change.
Direct Manipulation uses setNativeProps and Refs when frequent re-rendering creates a performance bottleneck.
Thanks for reading ! I hope you enjoyed and learned about the Direct Manipulation concepts in React Native. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.
Hello Readers, CoolMonkTechie heartily welcomes you in this article.
In this article, we will learn how to secure Mobile application in React Native. We will discuss Security related areas and techniques to secure mobile application. React Native is a popular cross-platform JavaScript framework. Components of React Native apps are rendered in Native UI. In this article, we will focus on the security side of the framework. In this article, we will focus on the security side of the framework.
A famous quote about learning is :
” Develop a passion for learning. If you do, you will never cease to grow.”
So Let’s begin.
Analyzing React Native
React Native has an alternative approach for cross-platform development. Traditionally, Cordova-based frameworks used WebView to render the whole application. In contrast, React Native applications run the JS code in a JavaScript VM based on JavaScriptCore. The application uses native JavaScriptCore on iOS and JavaScriptCore libs are bundled on an APK on Android.
In React Native, the communication between Native and JavaScript code is handled by a JavaScript Bridge. The source JS files are compiled into one single bundle file known as entry file. In development mode, the file is bundled on a local server and fetched by the application. For production, the application logic is usually bundled in a single file, usually “index.android.bundle” or “index.ios.bundle“.
Similarly to Cordova, the bundle file is present in the assets folder and, as also happens with Cordova, we can assume React Native apps as containers that run JS code. This logic is implemented in the expo. Under certain limitations, Expo can run different business logic in a single application. At this moment, it’s fair to assume the entry-file as the core application logic.
Major Sections of Secure Mobile Application
Secure Mobile Application is divided into three sections :
Securing application to server connection
Securing local storage
Advanced integrity checks
1. Securing Application to Server Connection
Usually, smartphone apps communicate with the backend server via APIs. Insecure Communication is highlighted in the OWASP Mobile Top 10 at #3:
” Mobile applications frequently do not protect network traffic. They may use SSL/TLS during authentication but not elsewhere. This inconsistency leads to the risk of exposing data and session IDs to interception. The use of transport security does not mean the app has implemented it correctly. To detect basic flaws, observe the phone’s network traffic. More subtle flaws require inspecting the design of the application and the applications configuration. – M3-Insecure Communication.“
Starting from iOS 9 and Android Pie, SSL is required by default. We can enable cleartext traffic but it’s not recommended. To secure the connection further, we can pin our server certificates.
SSL Pinning in React Native
Apps are dependent on Certificate Authorities (CA) and Domain Name Servers (DNS) to validate domains for TLS. Unsafe certificates can be installed on a user device, thereby opening the device to a Man-in-the-Middle attack. SSL pinning can be used to mitigate this risk.
We use the fetch API or libraries like axios or frisbee to consume APIs in our React Native applications. However, these libraries don’t have support for SSL pinning. Let’s explore the available plugins:
react-native-ssl-pinning: this plugin uses OkHttp3 on Android and AFNetworking on iOS to provide SSL pinning and cookie handling. In this case, we will be using fetch from the library to consume APIs. For this library, we will have to bundle the certificates inside the app. Necessary error handling needs to be implemented in older apps to handle certificate expiry. The app needs to be updated with newer certificates before certificates expire. This library uses promises and supports multi-part form data.
react-native-pinch: this plugin is similar to react-native-ssl-pinning. We have to bundle certificates inside the app. This library supports both promises and callbacks.
To use HPKP (Http Public Key Pinning), we can consider these plugins:
react-native-cert-pinner: this plugin allows us to use public hashes to pin the server. Unlike the plugins above, we can use fetch and other utilities directly. The pinning occurs before native JS is run. Also, there is no requirement to define hashes in the request itself.
react-native-trustkit: this is a wrapper plugin for the iOS Trustkit library. This library is available for iOS only.
2. Securing Local Storage
Normally, we store data inside our application to achieve offline functionality. There are multiple ways to store persistent data in React Native. Async-storage, sqlite, pouchdb and realm are some of the methods to store data.
Insecure storage is highlighted at #2 in the OWASP Mobile Top 10:
” Insecure data storage vulnerabilities occur when development teams assume that users or malware will not have access to a mobile device’s filesystem and subsequent sensitive information in data-stores on the device. Filesystems are easily accessible. Organizations should expect a malicious user or malware to inspect sensitive data stores. Usage of poor encryption libraries is to be avoided. Rooting or jailbreaking a mobile device circumvents any encryption protections. When data is not protected properly, specialized tools are all that is needed to view application data. – M2-Insecure Data Storage. “
Let’s take a look at some plugins which add a layer of security to our application. Also, we will be exploring some plugins which use native security features Keychain and Keystore Access.
SQLite
SQLite is the most common way to store data. A very popular and open-source extension for SQLite encryption is SQLCipher. Data in SQLCipher is encrypted via 256 bit AES which can’t be read without a key. React Native has two libraries that provide SQLCipher:
react-native-sqlcipher-2 : this is a fork of react-native-sqlite-2. We can use pouchdb as an ORM provider with this library, so it’s an additional bonus.
react-native-sqlcipher-storage : this is a fork of react-native-sqlite-storage. The library has to be set up manually since it doesn’t seem to support react-native link. Interestingly, the library is based on the Cordova implementation.
Realm
Realm is a nice alternative database provider to React Native Apps. It’s much faster than SQLite and it has support for encryption by default. It uses the AES256 algorithm and the encrypted realm is verified using SHA-2 HMAC hash.
Keychain and Keystore Access
Both iOS and Android have native techniques to store secure data. Keychain services allows developers to store small chunks of data in an encrypted database. On Android, most plugins use the Android keystore system for API 23(Marshmallow) and above. For lower APIs, Facebook’s conceal provides the necessary crypto functions. Another alternative is to store encrypted data in shared preferences.
React Native has three libraries that provide secure storage along with biometric/face authentication:
React Native KeyChain: As the name implies, this plugin provides access to keychain/keystore. It uses Keychain (iOS), Keystore (Android 23+), and conceal. There is support for Biometric Auth. This plugin has multiple methods and options for both Android and iOS. However, it only allows the storage of the username & password.
React Native Sensitive Info: This plugin is similar to React Native Keychain. It uses Keychain (iOS) and shared preferences (Android) to store data. We can store multiple key-value pairs using this plugin.
RN Secure Storage: This plugin is similar to React Native Sensitive Info. It uses Keychain (iOS), Keystore (Android 23+), and Secure Preferences to store data. We can store multiple key-value pairs.
3. Advanced Integrity Checks
JailMonkey and SafetyNet
Rooted and jailbroken devices should be considered insecure by intent. Root privileges allow users to circumvent OS security features, spoof data, analyze algorithms, and access secured storage. As a rule of thumb, the execution of the app on a rooted device should be avoided.
JailMonkey allows React Native applications to detect root or jailbreak. Apart from that, it can detect if mock locations can be set using developer tools.
SafetyNet is an Android-only API for detecting rooted devices and boot loader unlocks.
react-native-google-safetynet is a wrapper plugin for SafetyNet’s attestation API. It can be used to verify the user’s device.
Additionally, we can use react-native-device-info to check if an app is running in an emulator.
Protecting the Application Logic
Earlier in the article, we mentioned how the application logic in entry-file is available in plain sight. In other words, a third-party can retrieve the code, reverse-engineer sensitive logic, or even tamper with the code to abuse the app (such as unlocking features or violating license agreements).
Protecting the application logic is a recommendation in the OWASP Mobile Top 10. Specifically, the main concerns include code tampering:
” Mobile code runs within an environment that is not under the control of the organization producing the code. At the same time, there are plenty of different ways of altering the environment in which that code runs. These changes allow an adversary to tinker with the code and modify it at will. — M8-Code Tampering. “
And reverse engineering:
” Generally, most applications are susceptible to reverse engineering due to the inherent nature of code. Most languages used to write apps today are rich in metadata that greatly aides a programmer in debugging the app. This same capability also greatly aides an attacker in understanding how the app works. — M9-Reverse Engineering.”
Let’s highlight two different strategies to address this risk.
Hermes
Facebook introduced Hermes with the react-native 0.60.1 release. Hermes is a new JavaScript Engine optimized for mobile apps. Currently, it is only available with Android and it’s usage is optional. Hermes can be used in the project with react-native 0.60.4 by changing the enableHermes flag in build.gradle file.
Its key benefits are improved start-up time, decreased memory usage, and smaller app size. One of the strategies that Hermes uses to achieve this is precompiling JavaScript to bytecode.
Let’s look at a real example. We assume that our entry-file is the one found below:
const {createDecipheriv, createCipheriv, randomBytes} = require('crypto');
const key = Buffer.from('60adba1cf391d89a3a71c72a615cbba8', 'hex');
const algorithm = 'aes-128-cbc';
const softwareVersion = '2.0';
module.exports.createKey = function(userId, expireDate) {
const payload = {
userId,
expireDate,
softwareVersion
};
const json = Buffer.from(JSON.stringify(payload), 'utf8');
const iv = randomBytes(16);
const cipher = createCipheriv(algorithm, key, iv);
let encoded = cipher.update(json);
encoded = Buffer.concat([encoded, cipher.final()]);
const joined = iv.toString('hex') + ';' + encoded.toString('hex');
return Buffer.from(joined, 'utf8').toString('base64');
}
module.exports.validateLicense = function(license, userId) {
const licenseFields = Buffer.from(license, 'base64').toString('utf8');
const fields = licenseFields.split(';');
const iv = Buffer.from(fields[0], 'hex');
const data = Buffer.from(fields[1], 'hex');
const decipher = createDecipheriv(algorithm, key, iv);
let decoded = decipher.update(data);
decoded = Buffer.concat([decoded, decipher.final()]);
const result = JSON.parse(decoded);
if (result.userId != userId) {
throw new Error('Wrong user');
}
if (new Date(result.expireDate) < new Date()) {
throw new Error('Expired license');
}
if (result.softwareVersion != softwareVersion) {
throw new Error('This license is not valid for this program version');
}
return result;
}
After Hermes compiles this file, the resulting bytecode can easily be decompiled using hbcdump and, among the decompiled code, we find some easy to read code look like:
So, while Hermes introduces a certain degree of complexity to the entry-file code, it doesn’t actually conceal the code nor do anything to prevent code tampering, which means that it won’t stop an attacker — let’s not forget that this is not even the purpose of Hermes.
And this leads us to an approach that obfuscates React Native’s JavaScript source code to effectively mitigate the risk of code tampering and reverse engineering: Jscrambler.
Jscrambler
Jscrambler provides a series of layers to protect JavaScript. Unlike most tools that only include (basic) obfuscation, Jscrambler provides three security layers:
Polymorphic JavaScript & HTML5 obfuscation
Code locks (domain, OS, browser, time frame)
Self-defending (anti-tampering & anti-debugging)
By protecting the source code of React Native apps with Jscrambler, the resulting code is highly obfuscated, as can be observed below:
On top of this obfuscation, there’s a Self-Defending layer that provides anti-debugging and anti-tampering capabilities and enables setting countermeasures like breaking the application, deleting cookies, or destroying the attacker’s environment.
That’s all about in this article.
Conclusion
In this article, We learned how to secure Mobile applications in React Native. We discussed about Mobile application security related areas and techniques for React Native . It provides an overview of techniques to help to secure the React Native application. It’s then crucial to create a threat model , and depending on the application’s use case, employ the required measures to ensure that the application is properly secured.
Thanks for reading ! I hope you enjoyed and learned about the Mobile Application Security concepts in React Native. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.