• What is React Native
  • Pros and Cons of React Native App
  • IOS App development in React Native

React Native a.k.a Learn Once Write Everywhere

Facebook developers came up with the idea of making a platform where they can write code that can be used to develop both IOS and Android app back in 2013. So, they came up with the React Native platform that is written in JavaScript and React and can be rendered to IOS as well as Android UIX views. The idea behind it was  “Learn once, Use it anywhere”. React Native’s main strength is that it made the lives of IOS and Android developers easier because they do not have use to know both objective-C and Android Java to be able to develop IOS and Android apps. Additionally, IT companies can benefit a lot more because they do not have to hire two different developers for making IOS and Android apps, and it reduces time and cost significantly. Since then, both inside and outside of Facebook, the React Native community is increasing dramatically and it is also evolving day by day. Below, I would like to mention some of the pros and cons of React Native

Pros and Cons:

Before we start building a React Native IOS and Android app, I would like to mention some of the pros and cons of the React Native platform.

Pros:

  • FAST: As I mentioned earlier, making an Android and IOS app is much easier and faster with React Native because you write codes once and use this to render Android and IOS apps. That means, you do not have to write Android specific code which is Java and IOS app specific which is objective-C. There is the vastly growing React Native Community where you can get help when you encounter with an issue. And also, there are many ready-to-use components to apply when building your app. You can also use native app components but now there are only limited.
  • HOT LOADING: One of the great pros of React Native is that you can use Hot Loading to see changes in app immediately once you save your project. It saves a lot of time for developers to see changes on the spot and not forget the the state of the app when you alter UI. If you want to know more about Hot Loading, visit Here.
  • SMALLER BUT EFFECTIVE TEAMs: In order to build Native apps, companies need two different teams of Android and IOS and there might be miscommunication between teams or lagging one team behind making production date later.With React Native, companies need one team probably smaller and make both IOS and Android app, and also communication will be better as they are the same team.  

Cons:

  • Navigation: As everything comes with a price, React Native is not an exception. React Native has some drawbacks. The navigation bar does not feel like that of the native app, and it is not really user-friendly, as native apps do a better job in terms of navigation.
  • Facebook:As React Native belongs to Facebook, there is no way out of being dependent on Facebook because you have to Facebook licence to use React Native in your project. There is the possibility that Facebook may stop improving React Native frame at anytime. However, considering Facebook’s effort to make React Native secure and better and increase the community, it does not seem to be a possibility in the near future.
  • Reliance on Native: In order to use the camera, sensors or push notifications, you need to have at least a basic knowledge of IOS and Android app development because you cannot have access to the camera, sensors etc with React Native.

React Native app from scratch

First, you need to install Node in your computer if not installed before.You have to open your terminal if using Mac and type the following without $ sign.

$ pip install node

So, after installing Node, you are good to go to start React Native App.

Next, you need to run the following in your terminal without $ sign

$ npm install -g create-react-native-app

Now, it is time for us to create our first React Native app. To do that, run the following in the terminal.

$ create-react-native-app GreatProject

You can use a different name for your project but I used GreatProject as my project’s name.

If everything is fine and running well, you should see the following lines in your terminal

We suggest that you begin by typing:

 cd GreatProject

 yarn start

Happy hacking!

Now, on your phone, whether it be IOS or Android, download Expo app, which helps you to see your React native app and gets modified whenever you change your app, and connect it to the same wireless network as your computer. You can get more info Here . Go to GreatProject folder and it is at Users/your-user-name/GreatProject. For instance, mine is installed at

/Users/boburjonkobilov/GreatProject

Once you are inside the GreatProject folder, open app.js file with your own choice of edit.You will see the following source code.

One of my favorite ways of developing React Native app is through connecting Expo because on your own device, you can see your app in real time. To do so, install expo from the following link Expo XDE. Once you install it on your computer, open it and you will see the following user interface.

Press the “Open the existing project…” and find your GreatProject folder and upload it to Expo XDE run it. If no issue occurs, you will be seeing the following.

Go to Device icon on the right upper corner and choose the IOS or Android simulator that you would like to test your code on it. For IOS simulator, you need to have Xcode installed and you can download and install it at Here.

Once you open you open IOS simulator, you will be seeing the following screen on your IOS simulator device.

If you see this, it means that everything is fine and running well.

To keep everything simple and clean , let’s create a simple “To do list” IOS app.
Here, I would like to recommend using visual studio as your editor because I feel comfortable using it, but you can use any editor you want.

First, in order to keep things clean and separate, let’s create a ‘components’ folder inside ‘GreatProject’.This folder is where we will be saving .js files. Inside components folder, create ‘Main.js’ and below is the beginning source code of ‘Main.js file’ and this is going to be our main page when you open your app. Here is the beginning source code for Main.js

 

</pre>
&nbsp;

import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';

class Main extends Component {
render() {
return (
<View style={styles.container}>
<Text>This is main page!</Text>

</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default Main;
<pre>

Next, I am going to show final code of Main.js file and will explain step by step

</pre>
import React, { Component } from "react";
import {
AppRegistry,
StyleSheet,
Text,
View,
FlatList,
AsyncStorage,
Button,
TextInput,
Keyboard,
Platform
} from "react-native";
const isAndroid = Platform.OS == "android";
const viewPadding = 10;

class Main extends Component {
state = {
tasks: [],
text: ""
};

changeTextHandler = text => {
this.setState({ text: text });
};

addTask = () => {
let notEmpty = this.state.text.trim().length > 0;

if (notEmpty) {
this.setState(
prevState => {
let { tasks, text } = prevState;
return {
tasks: tasks.concat({ key: tasks.length, text: text }),
text: ""
};
},
() => Tasks.save(this.state.tasks)
);
}
};

deleteTask = i => {
this.setState(
prevState => {
let tasks = prevState.tasks.slice();

tasks.splice(i, 1);

return { tasks: tasks };
},
() => Tasks.save(this.state.tasks)
);
};

componentDidMount() {
Keyboard.addListener(
isAndroid ? "keyboardDidShow" : "keyboardWillShow",
e => this.setState({ viewMargin: e.endCoordinates.height + viewPadding })
);

Keyboard.addListener(
isAndroid ? "keyboardDidHide" : "keyboardWillHide",
() => this.setState({ viewMargin: viewPadding })
);

Tasks.all(tasks => this.setState({ tasks: tasks || [] }));
}

render() {
return (
<View
style={[styles.container, { paddingBottom: this.state.viewMargin }]}
>
<FlatList
style={styles.list}
data={this.state.tasks}
renderItem={({ item, index }) =>
<View>
<View style={styles.listItemCont}>
<Text style={styles.listItem}>
{item.text}
</Text>
<Button title="X" onPress={() => this.deleteTask(index)} />
</View>
<View style={styles.hr} />
</View>}
/>
<TextInput
style={styles.textInput}
onChangeText={this.changeTextHandler}
onSubmitEditing={this.addTask}
value={this.state.text}
placeholder="Add Tasks"
returnKeyType="done"
returnKeyLabel="done"
/>
</View>
);
}
}

let Tasks = {
convertToArrayOfObject(tasks, callback) {
return callback(
tasks ? tasks.split("||").map((task, i) => ({ key: i, text: task })) : []
);
},
convertToStringWithSeparators(tasks) {
return tasks.map(task => task.text).join("||");
},
all(callback) {
return AsyncStorage.getItem("TASKS", (err, tasks) =>
this.convertToArrayOfObject(tasks, callback)
);
},
save(tasks) {
AsyncStorage.setItem("TASKS", this.convertToStringWithSeparators(tasks));
}
};

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF",
padding: viewPadding,
paddingTop: 20
},
list: {
width: "100%"
},
listItem: {
paddingTop: 2,
paddingBottom: 2,
fontSize: 18
},
hr: {
height: 1,
backgroundColor: "gray"
},
listItemCont: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between"
},
textInput: {
height: 40,
paddingRight: 10,
paddingLeft: 10,
borderColor: "gray",
borderWidth: isAndroid ? 0 : 1,
width: "100%"
}
});
export default Main;
<pre>

First things first, we need to import built-in components from React and React Native. As you can see below, we are importing Stylesheet, Text, Flatlist AsyncStorage in our app project.

</pre>
import React, { Component } from "react";
import {
StyleSheet,
Text,
View,
FlatList,
AsyncStorage,
Button,
TextInput,
Keyboard,
Platform
} from "react-native";

I want to mention some of the components like Stylesheet and Asyncstorage.
Stylesheet is similar to CSS if you are familiar with Web Design. It is used to style your app and very important component for user interface.
AsyncStorage is a simple,unencrypted, asynchronous,persistent, key-value storage system that is global to IOS app. It should be used instead of global app. We will use to store our “To do list” data.

Platform is used to make platform-specific code because sometimes you want to use some components only for Android or IOS app. Here comes the use of platform component.
const isAndroid = Platform.OS == “android”;
As you can see above, we are declaring an instance of Platform.OS making it equal to Android and it can be used to check the device whether it is Android or IOS.

Next, we declare our Main class which extends from Component. We use to declare data in the constructor so that we can use it later in the app. For data that is going to be changed, we have to use state and so we used state and inside it we have tasks as a list and text as a string format.


class Main extends Component {
state = {
tasks: [],
text: ""
};

After we declare data in the constructor, it is time for us to declare functions that will be used in the app.


changeTextHandler = text => {
this.setState({ text: text });
};

We use changeTextHandler function to deal with what the user has entered. If we want to change data, we have to use setState in order to change data.

Next function is addTask which will be used to add task that the user has entered. You might be wondering why we declared a variable with let instead of var. The answer is that let statement declares a block scope local variable.In the first line, we check whether text entered is empty or not. If a user enter empty line, it will not be added to task.

 

</span>

addTask = () => {
let notEmpty = this.state.text.trim().length > 0;

if (notEmpty) {
this.setState(
prevState => {
let { tasks, text } = prevState;
return {
tasks: tasks.concat({ key: tasks.length, text: text }),
text: ""
};
},
() => Tasks.save(this.state.tasks)
);
}
};
<pre>

I want you to pay attention to the fact that we are saving data in localstorage in this function.

The following function is DeleteTask which will be used to delete a task.One important method here is splice() because with splice we can delete a task at a given index which is i in our case.

</pre>
deleteTask = i => {
this.setState(
prevState => {
let tasks = prevState.tasks.slice();

tasks.splice(i, 1);

return { tasks: tasks };
},
() => Tasks.save(this.state.tasks)
);
};
<pre>

We use componentDidMount() function to make sure that when we press keyboard, it will appear above the Add button. We add viewPadding to viewMargin so that it will appear above the button when the user wants to enter text. Keyboard.addListener() is used to detect whether keyboard is being used or not because if it is not, padding will be at its original place. Last but not the least is to save all the task from LocalStorage.

</pre>
componentDidMount() {
Keyboard.addListener(
isAndroid ? "keyboardDidShow" : "keyboardWillShow",
e => this.setState({ viewMargin: e.endCoordinates.height + viewPadding })
);

Keyboard.addListener(
isAndroid ? "keyboardDidHide" : "keyboardWillHide",
() => this.setState({ viewMargin: viewPadding })
);

Tasks.all(tasks => this.setState({ tasks: tasks || [] }));
}
<pre>

Next is render() method where all the components and UI will get rendered.The render() method is the only required method in class components which means that we have to use render() method all the time. We use <View> and inside it we use <FlatList> to make task list in simple flat layout. For getting input from an user, we use <TextInput> and inside it we call relevant functions that we have talked about above.

</pre>
render() {
return (
<View
style={[styles.container, { paddingBottom: this.state.viewMargin }]}
>
<FlatList
style={styles.list}
data={this.state.tasks}
renderItem={({ item, index }) =>
<View>
<View style={styles.listItemCont}>
<Text style={styles.listItem}>
{item.text}
</Text>
<Button title="X" onPress={() => this.deleteTask(index)} />
</View>
<View style={styles.hr} />
</View>}
/>
<TextInput
style={styles.textInput}
onChangeText={this.changeTextHandler}
onSubmitEditing={this.addTask}
value={this.state.text}
placeholder="Add Tasks"
returnKeyType="done"
returnKeyLabel="done"
/>
</View>
);
}
}

let Tasks = {
convertToArrayOfObject(tasks, callback) {
return callback(
tasks ? tasks.split("||").map((task, i) => ({ key: i, text: task })) : []
);
},
<pre>

References:

https://www.netguru.co/blog/react-native-pros-and-cons

https://facebook.github.io/react-native/

https://codeburst.io/todo-app-with-react-native-f889e97e398e