If you know JavaScript and are willing to develop a mobile app, React Native provides us with the ability to ship mobile apps with world-class user experience. Native app development targets a specific OS, like Android and iOS. Such development needs individual code base for each platform. Unlike native development, React Native helps developers reuse code across the platforms. Let’s go ahead and get the basic idea of React Native and build a simple application.
What is React Native?
React Native is a new way to build mobile apps. It’s a cross platform JavaScript framework created by Facebook. It allows developers to use JavaScript to create mobile apps for both Android and iOS with native look and feel.
- React Native is a JavaScript framework for building native mobile apps.
- Uses React framework.
- Offers a large number of inbuilt components and APIs to create UI and handle native features.
Prerequisites
- Solid JavaScript knowledge as it’s based on JavaScript framework.
- Understanding of ES6 as React native uses ES6 syntax extensively. Don’t sweat it, you can understand required concepts form this blog.
- Basic understanding of React JS. If you don’t know also it’s fine, you can learn while working on the application.
Advantages
- JavaScript
You can leverage your existing JavaScript knowledge to build mobile apps.
- Code Sharing
You can share most of your code (~90%) across different platforms.
- Fast development
One of the key benefits of React native is shorter development time. React native shares major code and you can potentially save time & money.
- Easy reloading
Don't recompile the application each time a change has been made. Just press Cmd+R to reload or refresh the app in the simulator, emulator or device.
- Community
React native is open source and the community around the React native is large.
Let’s get started and build a simple mobile app using React native. The final screen of the app will look something like below screenshot.
In this app, we end up building online shopping search page which will show all products listed. We can search different products by category or typing the product name in the search bar.
Let’s start with the installation.
Installation
React native installation is straightforward.
Step 1
Install Node JS. Please browse through this link and download Node JS (version > 6.0)
Step 2
Go to your command prompt and use npm to install the create-react-native-app. Run Command line – npm install -g create-react-native-app
Step 3
Run the following command to create a new project called “SampleApp”
- create-react-native-app SampleApp
- cd SampleApp
- npm start
This will start a development server and print a QR code in the terminal.
Step 4
Press any option you like to launch the app. I am choosing “a” as I am using Android emulator. Now you should able to see your first screen of the app.
Project Structure
After successful installation, we are good to go and can change or add code.
In the below screenshot we can see the folder structure of a newly created React native project.
Project Structure
Open the App.js file and change the existing text with any other verbiage and relaunch to make sure changes are reflecting properly.
- import React, {
- Component
- } from 'react';
- import {
- StyleSheet,
- Text,
- View
- } from 'react-native';
- export default class App extends Component {
- render() {
- return ( < View style = {
- styles.container
- } > < Text > Hello React native! < /Text> < /View>);
- }
- }
- const styles = StyleSheet.create({
- container: {
- flex: 1,
- backgroundColor: '#fff',
- alignItems: 'center',
- justifyContent: 'center',
- },
- });
As IDE, I am using Visual Studio Code but any other JavaScript editor can be used for developing React native code.
This is the output after changing the App.js file
Debugging
Press cmd + M (Android) and cmd + D (iOS) when app is open in the simulator/emulator. This will end up opening a dialog with different development menu.
To reload the app, we can choose “Reload” from the options or we can use keyboard cmd + R (iOS) and tap R twice (Android).
To debug the JavaScript code in the Chrome (browser), select “Debug JS Remotely” from the development menu. After choosing the option, a Chrome window will be opened in a new tab at http://localhost:8081/debugger-ui. Here in the below screenshot, we can see the Chrome developer tool sources tab lists all application files. We can put the break point and debug the code.
Build Application
Let’s go ahead and start implementation.
To design UI of the list page, we need a couple of controls to be imported from React-native library. I am importing all of them (TextInput, FlatList, Image, Picker, TouchableHighlight).
- import React, {
- Component
- } from 'react';
- import {
- StyleSheet,
- Text,
- TextInput,
- FlatList,
- Image,
- Picker,
- TouchableHighlight,
- View
- } from 'react-native';
- export default class App extends Component {
- render() {
- return ( < View style = {
- styles.container
- } > < Text > Hello React native! < /Text> < /View>);
- }
- }
- const styles = StyleSheet.create({
- container: {
- flex: 1,
- backgroundColor: '#fff',
- alignItems: 'center',
- justifyContent: 'center',
- },
- });
We need a local database where we put details of all products. I have created a JavaScript array of objects which will work as a database. ProductList is the array which is holding a bunch of objects and each object has six properties: key, name, price, category, imageUrl and CTYPE (categroty type).
- import React, {
- Component
- } from 'react';
- import {
- StyleSheet,
- Text,
- TextInput,
- FlatList,
- Image,
- Picker,
- TouchableHighlight,
- View
- } from 'react-native';
- var ProductList = [{
- key: 1,
- name: "Apple iPhone 7 Plus (Jet Black, 128GB)",
- Price: "Rs. 80,200",
- Category: "Mobile",
- imageUrl: require('./images/51Cqn38lCEL.jpg'),
- CTYPE: "M"
- }, {
- key: 2,
- name: "Apple iPhone 6s (Space Grey, 32GB)",
- Price: "Rs. 40,200",
- Category: "Mobile",
- imageUrl: require('./images/71c8c5OWqgL._SL1500_.jpg'),
- CTYPE: "M"
- }, {
- key: 3,
- name: "Samsung Galaxy On8 (Gold, 3 GB RAM + 16 GB Memory)",
- Price: "Rs. 13,000",
- Category: "Mobile",
- imageUrl: require('./images/71mtqsPn0HL._SL1500_.jpg'),
- CTYPE: "M"
- }, {
- key: 4,
- name: "G-Shock Analog-Digital Black Dial Men's Watch - GA-1100-2ADR(G597)",
- Price: "Rs. 12,009",
- Category: "Watch",
- imageUrl: require('./images/910C9-8r6+L._UL1500_.jpg'),
- CTYPE: "W"
- }, {
- key: 5,
- name: "Fastrack New OTS Analog Black Dial Men's Watch",
- Price: "Rs. 1,500",
- Category: "",
- CTYPE: "Watch",
- imageUrl: require('./images/81r-yEx3I6L._UL1500_.jpg'),
- CTYPE: "W"
- }, {
- key: 6,
- name: "Tommy Hilfiger Men's Cool Sport Analog Display Quartz Blue ",
- Price: "Rs. 10,000",
- Category: "Watch",
- imageUrl: require('./images/91-DKgb4KdL._UL1500_.jpg'),
- CTYPE: "W"
- }, {
- key: 7,
- name: "Fossil Machine Chronograph Black Dial Men's Watch",
- Price: "Rs. 7,995",
- Category: "Watch",
- imageUrl: require('./images/81Op2jBEg8L._UL1500_.jpg'),
- CTYPE: "W"
- }, {
- key: 8,
- name: "boAt Rockerz 510 Wireless Bluetooth Headphones (Black)",
- Price: "Rs. 1,919",
- Category: "HeadPhone",
- imageUrl: require('./images/71FUKZe4cfL._SL1500_.jpg'),
- CTYPE: "H"
- }, {
- key: 9,
- name: "Sony Extra Bass MDR-XB650BT Wireless Headphones (Blue)",
- Price: "Rs. 6,900",
- Category: "HeadPhone",
- imageUrl: require('./images/51ivKj0Wt6L._SL1000_.jpg'),
- Category: "H"
- }, {
- key: 10,
- name: "Sennheiser HD 4.40-BT Bluetooth Headphones (Black)",
- Price: "Rs. 10,990",
- Category: "HeadPhone",
- imageUrl: require('./images/41Ooz6Kj8fL.jpg'),
- CTYPE: "H"
- }];
Next we are binding the product list to the FlatList. Here we can see the react specific terms like props and state. You can get the details of it from this URL. For now,
- Props
Properties are passed to a component and can hold data. But this cannot be changed inside components.
- State
State is used to refresh or update values in the component. Each time When “setState” method is called, the render() function in the Component will be called simultainously.
Here we are assigning the poduct list as state and setting it as data of FlatList fetching it from the state.
- export default class ListApp extends Component {
- constructor(props) {
- super(props);
- this.state = {
- type: "A",
- lvDataSource: ProductList
- }
- }
- render() {
- return ( < View style = {
- styles.container
- } > < FlatList data = {
- this.state.lvDataSource
- }
- keyExtractor = {
- (item, index) => 'list-item-${index}'
- }
- renderItem = {
- ({
- item
- }) => < View style = {
- {
- flex: 1,
- flexDirection: 'row',
- alignItems: 'center'
- }
- } > < Image source = {
- item.imageUrl
- }
- style = {
- {
- width: 40,
- height: 40,
- margin: (0, 5, 0, 5)
- }
- }
- /> < View > < Text style = {
- {
- width: 300,
- color: 'darkblue'
- }
- } > {
- item.name
- } < /Text> < Text style = {
- {
- color: 'brown',
- fontWeight: 'bold'
- }
- } > {
- item.Price
- } < /Text> < /View> < /View>
- }
- /> < /View>);
- }
- }
So far so good and this is the product list.
Now we have product list on screen and we would like to search required product and add a header image.
We need to implement text input and picker callbacks to filter out product from the list. OnChange event for text input and onValueChange event for picker needs to be handled filtering products based on typed text in the text input or selected value from the picker. This is the implementation with code snippet.
- export default class ListApp extends Component {
- constructor(props) {
- super(props);
- this.state = {
- type: "A",
- lvDataSource: ProductList
- }
- }
- _onTextChanged = (e) => {
- var SearchedList = [];
- var enteredText = e.nativeEvent.text;
- var selectedType = this.state.type;
- if (selectedType == "A") {
- SearchedList = ProductList.filter(function(product) {
- return (product.name.toLowerCase().indexOf(enteredText.toLowerCase()) > -1);
- });
- } else {
- SearchedList = ProductList.filter(function(product) {
- return (product.CTYPE == selectedType && product.name.toLowerCase().indexOf(enteredText.toLowerCase()) > -1);
- });
- }
- this.setState({
- lvDataSource: SearchedList
- });
- }
- _onValueChanged = (v, i) => {
- this.setState({
- type: v
- });
- if (v == "A") {
- this.setState({
- lvDataSource: ProductList
- });
- } else {
- var selectedList = ProductList.filter(function(product) {
- return (product.CTYPE == v);
- });
- this.setState({
- lvDataSource: selectedList
- });
- }
- }
- render() {
- return ( < View style = {
- styles.container
- } > < View > < Image source = {
- require('./images/estore.jpg')
- }
- /> < Text style = {
- {
- fontWeight: 'bold'
- }
- } > Search by: < /Text> < Picker selectedValue = {
- this.state.type
- }
- onValueChange = {
- this._onValueChanged
- } > < Picker.Item label = "All Category"
- value = "A" / > < Picker.Item label = "Mobile"
- value = "M" / > < Picker.Item label = "Watch"
- value = "W" / > < Picker.Item label = "Head phones"
- value = "H" / > < /Picker> < TextInput style = {
- {
- height: 45,
- width: 800
- }
- }
- onChange = {
- this._onTextChanged
- }
- placeholder = "Type here to search!" / > < /View> < FlatList data = {
- this.state.lvDataSource
- }
- keyExtractor = {
- (item, index) => 'list-item-${index}'
- }
- renderItem = {
- ({
- item
- }) => < View style = {
- {
- flex: 1,
- flexDirection: 'row',
- alignItems: 'center'
- }
- } > < Image source = {
- item.imageUrl
- }
- style = {
- {
- width: 40,
- height: 40,
- margin: (0, 5, 0, 5)
- }
- }
- /> < View > < Text style = {
- {
- width: 300,
- color: 'darkblue'
- }
- } > {
- item.name
- } < /Text> < Text style = {
- {
- color: 'brown',
- fontWeight: 'bold'
- }
- } > {
- item.Price
- } < /Text> < /View> < /View>
- }
- /> < /View>);
- }
- }
Let’s see how it’s working in action.
There we go, based on search text black the product list is filtered accordingly.
Let’s search by category as well. As Watch is selected from the picker, all watches are listed.
Great! We completed a sample application which is listing a bunch of products and searching/filtering them. Code attached along with this blog, you can download and go through.
This is the basic application to jump-start React native.
Every technology has certain downsides and React native is not an exception. So, before choosing React native for our project we need to consider those points as well,
- It is good for building less responsive apps like social, e-commerce, data-entry etc. but not good for high performance apps like games.
- It is new so many libraries are still to be added, so it can help in building small applications but the developer can get stuck in between if they build large apps and want to go deeper in the framework.
- Implementing some native features requires detailed knowledge of a platform.
- Learning curve may be a concern if you are new to JavaScript and unaware of other cross-platform or hybrid frameworks like Cordova.