React Native is one of the most famous open-source hybrid frameworks to build apps for Android, iOS, and web platforms using JavaScript with a single codebase.
The name “React Native” is composed of two words: React and Native. “React” states the use of the React app development environment, and “Native” represents the use of native Android/iOS/Web UI widgets to develop apps for better performance. React Native interacts with the Native platform at runtime via JavaScript to construct the native view for React Native UI components. React Native also offers ready-to-use inbuilt APIs for UI development such as <ScrollView>
, <FlatList>
, <ImageView>
, etc. to develop apps.
This guide covers the basics of React Native development on Android using the standard npx react-native
CLI.
React Native is built upon the React framework, but it uses different APIs and technologies to make React apps compatible with the Native mobile platform:
DOM
or window
object.native module
to create a wrapper to use platform-specific APIs or third party modules.As mentioned earlier, the standard React Native create-react-native-app
CLI requires the Native development tools (Android Studio or XCode) and other npm packages, such as Camera and Map, to build specific features. Expo CLI overcomes the limitations of standard React Native CLI with the following features:
Expo is an enhanced version of the standard React Native CLI for quick design, development, and publishing, but despite many pros Expo has some limitations:
Expo is an easy way to get started quickly with React Native development in browsers. Expo also supports unimodules to use Expo SDK in React Native apps.
React Native follows the similar development structure and tools of React, so this guide assumes that you have the basics knowledge of following technologies and tools.
The npx react-native init
requires external tools, so follow the below steps to download and install the required tools, as per operating system:
Verify Homebrew installation using brew -v
, and if Homebrew is not installed then install Homebrew using
1/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
Note: Homebrew installation requires the xcode-select
command-line tool to work so it's recommended to install Xcode as well or it will ask to confirm the installation of xcode-select
tool.
node
and watchman
1brew install node watchman
break cask
to install GUI software installation setups1brew cask install adoptopenjdk/openjdk/adoptopenjdk8
1# can use any editor instead of open
2open ~/.bash_profile
1# after other pre-configured environment variables
2export ANDROID_HOME=$HOME/Library/Android/sdk
3export PATH=$PATH:$ANDROID_HOME/emulator
4export PATH=$PATH:$ANDROID_HOME/tools
5export PATH=$PATH:$ANDROID_HOME/tools/bin
6export PATH=$PATH:$ANDROID_HOME/platform-tools
MacOS Cataline has a default shell as zsh
so to fix the warning below, edit/create ~/.zprofile
(under /users/username/
) file for Cataline.
1chsh -s /bin/zsh
2# create the .zprofile under users/your_user_name and copy content from bash_profile, save it
3source ~/.zprofile
printenv
prints all environment variables.xcode-select --version
allows you to view the version of xcode-select CLI.1choco install -y nodejs.install python2 openjdk8
UserName
with your username:1setx ANDROID_HOME "C:\Users\UserName\AppData\Local\Android\SDK"
and add platform-tools
to PATH
variable. Make sure to replace UserName
with your user name:
1setx /M PATH "%PATH%;C:\Users\UserName\AppData\Local\Android\SDK\platform-tools"
The steps to run the project is the same on all operating systems:
1npx react-native init RNClickCounter
1cd RNClickCounter
2npx react-native run-android --verbose
The above command process may ask to install CocoaPods
, which is a dependency manager for iOS projects and required to run iOS apps.
In the above command, --verbose
is optional but useful to view any potential issues, like below.
InvokerHelper Error
: Gradle version 6.1.1
can cause this issue, so make sure to update distributionUrl
attribute in RNClickCounter\android\gradle\wrapper\gradle-wrapper.properties
file:1# To fix the "Could not initialize class org.codehaus.groovy.runtime.InvokerHelper" error, use latest gradle
2distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip
and update classpath in RNClickCounter\android\build.gradle
:
1classpath("com.android.tools.build:gradle:4.0.0")
Note: React Native may not use the exact buildToolsVersion
version declared in the RNClickCounter/android/build.gradle
file, so in case of error the specific version needs to be installed from the Android SDK.
The project structure of a React Native project is similar to React. The underlying Android and iOS project is pre-configured to use React components to build platform-specific apps.
Let's go through the key elements of a React Native project:
Index.js
is an entry point for a React app to register the app and to load required modules for the JS executions environment.App.js
is the first/main screen of the app.android
folder contains all the Native Android development, and build files, which is almost similar to the Native Android project structure.ios
folder contains all the Native iOS development and build files, which is almost similar to the Native iOS project structure.package.json
contains the details about the app (name, version), dependencies, and executable script details.app.json
contains the app name details.React Native uses some common mobile components like Button
, View
, Text
, etc., along with React Native-specific components like SafeAreaView
and StyleSheet
. Let's go though some basic components to build the click counter app:
SafeAreaView
adds the required padding for camera-notches/sensor-housing and reflects the area that is not covered by any of the top views like toolbar, navigation, etc.Text
displays text on the screen. It is similar to UILabel
, TextView
, or <p>
tag.View
is a basic UI container element with flexbox layout support. The Native equivalents of view are UIView
, View
, or div
tag.Button
represents the Native platform-specific button with platform-specific style.StyleSheet
is used to define the style attributes for elements that will be mapped to Native-style values.useState
is a React hook that is used to maintain a state (stored values) in a functional component. This is used in the App.js
functional component to keep the track of the counter variable’s state. The counter variable should be modified by the callback method setCount
, and returned by useState
.export default App
is used to allow other components to import the App
component. There can be only one default export in a file.flex: 1
is used to define the CSS3 flexbox style responsive layout vertically.React$Node
represents a type of React node (from flow type check) whose value can be a ReactChild, ReactFragment, ReactPortal, boolean, null, number, or string.Follow the below steps to implement click counter in the App.js
component:
react-hook
to store the updated value of count
. The setCount
method will be used to update the value of count
:1 const [count, setCount] = useState(0);
count
:1 const counterPlus = () => {
2 setCount(count + 1 <= Number.MAX_SAFE_INTEGER ? count + 1 : count)
3 }
4
5 const counterMinus = () => {
6 setCount(count - 1 >= Number.MIN_SAFE_INTEGER ? count - 1 : count)
7 }
Button
and Text
:1const styles = StyleSheet.create({
2 container: {
3 flex: 1,
4 justifyContent: 'center',
5 alignItems: 'center',
6 backgroundColor: '#e6e6fa',
7 },
8 textConter: {
9 fontSize: 28,
10 color: '#000',
11 },
12 buttonStyle: {
13 width: "80%",
14 margin: 10,
15 }
16});
1import React, { useState } from "react";
2import { SafeAreaView, StyleSheet, Text, StatusBar, Button, View} from 'react-native';
3
4const App: () => React$Node = () => {
5
6 const [count, setCount] = useState(0);
7
8 const counterPlus = () => {
9 setCount(count + 1 <= Number.MAX_SAFE_INTEGER ? count + 1 : count)
10 }
11
12 const counterMinus = () => {
13 setCount(count - 1 >= Number.MIN_SAFE_INTEGER ? count - 1 : count)
14 }
15
16 return (
17 <>
18 <StatusBar barStyle="dark-content" />
19 <SafeAreaView style={styles.container}>
20 <Text style={styles.textConter} >{count}</Text>
21 <View style={styles.buttonStyle}>
22 <Button
23 onPress={counterPlus}
24 title='+' />
25 </View>
26 <View style={styles.buttonStyle}>
27 <Button
28 onPress={counterMinus}
29 title='-' />
30 </View>
31 </SafeAreaView>
32 </>
33 );
34};
35
36const styles = StyleSheet.create({
37 container: {
38 flex: 1,
39 justifyContent: 'center',
40 alignItems: 'center',
41 backgroundColor: '#e6e6fa',
42 },
43 textConter: {
44 fontSize: 28,
45 color: '#000',
46 },
47 buttonStyle: {
48 width: "80%",
49 margin: 10,
50 }
51});
52
53export default App;
React Native is a great way to build hybrid apps. You can either use Expo
or npx react-native
CLI to get started with React Native development.
The optimized codebase is available at RnClickCounter repository. Hopefully, this guide explained the necessary details to get started with React Native on Android. Happy Coding!