What is React Native?
React Native is an open-source mobile application framework created by Facebook. It is used to develop applications for Android, iOS, Web and UWP by enabling developers to use React along with native platform capabilities.
Although they share a name, ReactJS and React Native are quite different and it’s difficult to understand React Native without first being familiar with ReactJS.
You don’t have to be an expert in React, but understanding the flow of data through the React framework helps with comprehending React Native. Regardless, I will give a higher-level overview of what React Native does.
React Native is Javascript that can run on devices outside of web browsers. First, the library abstracts aspects that are common across user interfaces, like views, text, buttons, animation, etc. Next, a developer creates components that are written in Javascript and combines them to form a native application.
Finally, the application is run on native platform user interfaces. The most common types of native platform user interfaces that React Native apps run on are Android and iOS devices. These are typically mobile applications.
SDKs
If the application was only written using React Native then the application could be used on either iOS or Android devices. However, you have probably heard, the app is only available on Android. You could easily swap Android for Apple in the last sentence, the point is, if React Native can be used for either device why are certain platform applications released at different times? The answer can be explained by varying Software Development Kits (SDKs).
Android and iOS phones have different operating systems. Therefore;
- files are accessed differently
- not all user interactions with the device are the same
- storage and network capabilities can vary
And that’s only to name a few of the differences. Consequently, these platforms need specific libraries that can be used with React Native for application features on their devices.
The application that we create later will not use Android or iOS SDKs for the sake of simplicity, but there is no shortage of information on how to download and use these libraries with React Native.
Differences Between ReactJS and React Native
Here is an example of a ReactJS component,
import React from 'react' const Example = (props) => { return ( <div> <p>Hello world!</p> </div> ) } export default Example
and here is an example of the same component written with React Native.
import * as React from 'react'; import { Text, View } from 'react-native'; const ExampleScreen = (props) { return ( <View> <Text>Hello world!</Text> </View> ) } export default ExampleScreen
<div>
and <p>
HTML elements are replaced by <View>
and <Text>
components. This can best be explained with the observation that React Native apps are not run in a web browser.
DOM
In a normal ReactJS web application, React takes control of the Document Object Model (DOM) provided by the browser and controls what is rendered. Furthermore, it creates a virtual DOM to extend its control over the rendering process. The DOM is a tree-like structure where HTML elements are either children or parents of other HTML elements. However, in a React Native app, there isn’t a browser. Consequently, there is no HTML. This throws a wrench into the relationship that React had with the DOM and HTML.
Furthermore, this means that Javascript libraries that render HTML code cannot be used with React Native.
One of the positives of using React Native is that we can still control what components are rendered to the screen by using conditionals, but instead of JSX that is compiled to HTML, the React Native components (ie <View>
and <Text>
) are compiled into native code.
Styling
No HTML means no CSS files. Subsequently, there is not a className
property for components. However, many of the same CSS styling conventions are still available. Using ReactJS inline-styles is similar to React Native styling. Again, let’s look at an example;
import React from 'react' const Example = (props) => { return ( <div style={{ background: "#0000FF" }}> <p style={{ color: "#FFF", marginBottom: "20px" }} >Hello world!</p> </div> ) } export default Example
The above component uses inline styling to give the container a blue background and the text is white. Let’s apply this styling to a React Native component.
import * as React from 'react'; import { Text, View, Stylesheet } from 'react-native'; const ExampleScreen = (props) { return ( <View style={styles.containerStyling}> <Text style={styles.textStyling}>Hello world!</Text> </View> ) } const styles = StyleSheet.create({ containerStyling: { background: '#0000FF', }, textStyling: { marginBottom: 20, color: '#FFF', } }); export default ExampleScreen
Let’s take a look at the differences:
Stylesheet
is imported from React Native and is used to make create styling objects- Units are numbers and not strings
- Styles are accessed on the
styles
object (this is similar to modular styling in ReactJS web applications)
It takes some adjusting to get used to the subtle differences, but most of the same functionality remains intact. One surprising aspect was that some components, like button and images, do not have a style
prop. Consequently, these components need to be wrapped in a styled View
component.
Continued Differences
There are differences in navigating between views (pages), creating links, etc. We are going to touch on those differences during the example application later. However, before getting into the application I want to talk about the development environment.
Expo
The React Native environment set up documentation has two ways to get started building a React Native application.
- Expo CLI
- React Native CLI
The React Native CLI has instructions for the various major operating systems (Mac, Windows, Linux) and how to download and configure iOS and Android simulators for each platform. It’s outside the scope of this article to go into the details of setting up different platform-specific environments that, subsequently, have embedded platform-specific environments.
Furthermore, it’s worth noting that iOS simulators are not supported on Windows.
Instead, we are going to use Expo, which is the fastest and easiest way for us to build a React Native application.
Expo is a framework and a platform for universal React applications. It is a set of tools and services built around React Native and native platforms that help you develop, build, deploy, and quickly iterate on iOS, Android, and web apps from the same JavaScript/TypeScript codebase.
The development server is run on your local desktop but the simulator is your smartphone. You can connect your smartphone to your development server using the Expo client app and, if you are connected to the same network, view your live development updates on your smartphone. I will do a walk-through of the set up in the application tutorial.
Expo also supports running the app with Android and iOS simulators on your desktop if you desire to set that up in the future.
Be advised, before you start building a massive application with Expo, that they are not shy about their limitations. That being said, they make it very easy to get started with React Native and I think you will find the process to be easy and enjoyable! Let’s get started!
How to Create a React Native App
Prerequisites
- Wireless internet connection that both your phone and laptop/desktop can connect to
- NodeJS 12 LTS or greater installed locally. There are installation instructions on NodeJS.org.
- Expo requires Git. You can download Git from here.
- The minimum operating system requirements for smartphones are:
- Android version is Lollipop (5)
- iOS version is iOS 10.0
- Basic understanding of ReactJS or Javascript
- Expo client application downloaded on your smartphone
- Understanding of how to open a terminal, or command-line on your machine
1. Project Set-Up
Open up a new terminal and run the following commands
$ npm install -g expo-cli $ expo init rapidapi-react-native
You are then prompted for the type of project to initialize by the expo-cli. Choose the managed workflow, tabs.
After the project installs change directories into the new project. This is typically done with the command cd
.
cd rapidapi-react-native/
In the apps root directory, run the command npm start
and grab your smartphone.
Check to make sure that both your smartphone and computer are connected to the same wireless network.
If you are using Android, use the Expo client app to scan the QR-code that appears in the terminal (or the Qr-code in the web browser). If you are using iOS, you can use the camera’s built-in QR-code scanner. Select the camera app and point it at the QR-code.
After scanning, the Expo app opens and the Javascript bundle starts to build. This can take a couple of minutes. When it finishes, our app should appear with the template code. Your smartphone should now show the template code for our project!
File Structure
Next, open up the project with your code editor.
Take a moment to examine the file structure. The project starts at the App.js
file.
In App.js
, the main app layout is created and managed by the NavigationContainer
component that accepts the LinkingConfiguration
import.
Notice that the LinkingConfiguration
file has the same screen options that are found in the screens
folder.
Furthermore, the screens
and navigation
folders are where we are going to spend the majority of our time.
2. Change Navigation
Understanding navigation is an important step in our application. Open up BottomTabNavigator.js
.
This page controls the navigation of our application, much like a navigation bar (or menu) would control navigation in a web application. It’s an important file!
Our application is going to be a simple coin-flipping app that sends an API request when the user hits a button to fetch a result. Our two tabs will be ‘Flip Coin’ and ‘Resources’.
In BottomTabNavigator.js
, change the title option of the home screen from 'Get Started'
to 'Flip Coin'
.
Our app, running on our smartphone, should reflect this change! One of the tabs should now be Flip Coin. If your app did not update, you may need to reopen the application from the Expo client.
There is a helper function at the bottom of BottomTabNavigator.js
named getHeaderTitle
that returns the header title for each home screen. Change the header title of 'Home'
from 'How to get started'
to 'Coin Toss!'
. Again, the app should reflect the new change!
Icons
Icons tend to play an essential role in mobile applications. Fortunately, our app came with the TabBarIcon
component to help us render icons. Also, Expo provided a vector icon library so we can easily change icons in our app.
Open up TabBarIcon.js
and change the top import line to,
import { MaterialCommunityIcons } from '@expo/vector-icons';
Ionicons
for MaterialCommunityIcons
. Then, change the component name in the return statement from Ionicons
to MaterialCommunityIcons
BottomTabNavigator.js
, change the prop name
on the home TabBarIcon
component to 'coin'
.'link'
. You can view more icon options for Expo by visiting their icons page.3. Add Coin Flip
Open up HomeScreen.js
. This page has a lot of code that we are not going to use. Therefore, remove all the code inside and add the code below to clean things up.
import * as React from 'react'; import { Image, Animated, StyleSheet, Alert, Text, View, Button, ActivityIndicator, Easing } from 'react-native'; import { ScrollView } from 'react-native-gesture-handler'; export default function HomeScreen() { return ( <View style={styles.container}> <ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}> <View style={styles.flipContainer}> <Text style={styles.flipTitle}>Flip On It!</Text> <Text style={styles.basicText}>An app to help you achieve even odds in the digital age!</Text> </View> </ScrollView> </View> ); } HomeScreen.navigationOptions = { header: null, }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', }, contentContainer: { paddingTop: 30, }, coinImageContainer: { alignItems: 'center', marginTop: 10, marginBottom: 20, }, welcomeImage: { width: 150, height: 124, resizeMode: 'contain', marginTop: 3, marginLeft: -10, }, flipContainer: { alignItems: 'center', marginHorizontal: 50, }, flipTitle: { fontSize: 25, color: '#000', marginVertical: 8, paddingTop: 10, paddingHorizontal: 10, lineHeight: 24, textAlign: 'center', }, basicText: { fontSize: 15, color: 'rgba(96,100,109, 1)', lineHeight: 18, textAlign: 'center', }, flipResultText: { fontSize: 35, color: '#FF0000', textAlign: 'center', fontWeight: "700" }, buttonContainer: { backgroundColor: "#1a1aff", marginTop: 16, marginBottom: 16, borderRadius: 5, paddingVertical: 4, paddingHorizontal: 5, } });
The above code contains CSS styles, created with StyleSheet.create({})
, that we are going to use later. Furthermore, at the top, the code imports all the components from React Native that we are going to use.
However, currently, the app has a few simple components. Remember, View
is like a div
and Text
is like a p
element or h1
element. Your smartphone should now look like the screenshot below.
Button
Next, let’s add the button that controls when to flip the coin. The React Native button component does not have a style component, so we use a wrapping View
component to style the button. Add the button below underneath the app description text component (has the text An app to help you achieve even odds in the digital age!) in HomeScreen.js
.
<View style={styles.buttonContainer}> <Button title="Flip Coin" onPress={() => fetchData()} color="#FFFFFF" accessibilityLabel="Fetch heads or tails" /> </View>
The component calls the fetchData
function when it is pressed. However, this function does not exist yet. Add the function to the component above the return statement.
const fetchData = () => { console.log('flipped') };
To view the console.log()
output, select your device in the browser that Expo opened when the app was started. There, you can see the output from the application.
I have, obviously, hit the flip button a few times.
Image
Next, let’s add an image to our app.
At the top of the <ScrollView>
components, add the image component,
<Image source={{ uri: 'https://cdn.pixabay.com/photo/2018/05/17/00/24/quarter-3407493_960_720.png' }} style={styles.welcomeImage} />
Images can be added from the project filesystem, from a URI, or by data (base64). The dimensions of the image need to be specified if using a URI or data encoded. We are specifying image dimensions in the style object with welcomeImage
style. The image isn’t centered yet because we are not done with it.
Animation
Animations are very different compared to animations with a web application. Animations are achieved with the Animated
component and there are a series of methods that can be called to handle events. A deeper dive into animations is beyond this application, but let’s implement one anyway.
At the top of the component, above fetchData
, initialize our animation parameter with the line below.
const rotateAnim = React.useRef(newAnimated.Value(0)).current
const startFlip = () => { Animated.timing( rotateAnim, { toValue: 100, easing: Easing.inOut(Easing.exp) } ).start(); } const resetFlip = () => { Animated.timing( rotateAnim, { toValue: 0, } ).reset(); }
Since we cannot animate the image directly, we are going to wrap it in an animated component.
Replace the Image
component with the Animated.View
component below.
<Animated.View style={{ ...styles.coinImageContainer, transform: [ { scale: 1.1 }, { rotateX: rotateAnim }, { perspective: 1000 } ] }}> <Image source={{ uri: 'https://cdn.pixabay.com/photo/2018/05/17/00/24/quarter-3407493_960_720.png' }} style={styles.welcomeImage} /> </Animated.View>
We still have the image tag as a child of the animation component, but this is the necessary set up for animated components.
startFlip
function to fire when we run fetchData
by adding a function call to the top the fetchData
function.const fetchData = () => { startFlip() // added console.log('flipped') };
Now, the coin image is centered and flips the first time we hit the Flip Coin button. However, it only works once because we haven’t added the resetFlip
function call to fetchData
yet. That will be done when we implement the API call.
4. Make API Call with React Native
In order to finish the application with an API call, you need to have an account on RapidAPI.
Sign Up For a Free Account on RapidAPI
Visit RapidAPI to get signed up if you haven’t already!
Inspect the Coin Flip API on RapidAPI
The Coin Flip API has one endpoint that returns one parameter. It’s a simple and free API, that we can use for the purpose of our simple application.
Notice I have selected the (Javascript) fetch code snippet. This helps us create our API for the given language and library.
Add API call to HomeScreen.js
First, initialize two state variables below the rotateAnim
variable.
const [isLoading, setLoading] = React.useState(false); const [data, setData] = React.useState('');
Next, replace code inside of fetchData
with the code below.
const fetchData = () => { startFlip() setLoading(true); fetch('https://coin-flip1.p.rapidapi.com/headstails', { "method": "GET", "headers": { "x-rapidapi-host": "coin-flip1.p.rapidapi.com", "x-rapidapi-key": 'apikey' } }) .then((response) => response.json()) .then((json) => setData(json.outcome)) .catch(() => Alert.alert('Something went wrong..', 'There was an error fetching coin flip.')) .finally(() => { setLoading(false) resetFlip() }); };
Add API-key
Never store sensitive API keys in your app code. Anything included in your code could be accessed in plain text by anyone inspecting the app bundle. Tools like react-native-dotenv and react-native-config are great for adding environment-specific variables like API endpoints, but they should not be confused with server-side environment variables, which can often contain secrets and api keys.
We are going to add a sensitive API key to our project. This makes the application not suitable for production. Furthermore, the application is not suitable to be pushed to a git repository because the API-key is hardcoded into the project. To read more about securing API keys for production, visit the React Native security page.
Although there is a clear process for environment variables when using a traditional React Native set up, there is not a clear set-up for environment variables when using Expo. Therefore, I am asking you to replace the string 'apikey'
with the API key found on your dashboard. You can locate this value using the dashboard image above. I have a red line blocking the value of my API key.
This is not mandatory, and it will comprise your key if put into production or pushed to a Git repository. However, it gives the application better functionality and is safe to use for our locally running application.
After adding the key, the coin flips every time we press the button, but we need to add a component to display the result!
Finally, place this small <View>
component underneath the Animated.View
component.
<View style={{ padding: 24 }}> {isLoading ? <ActivityIndicator /> : <Text style={styles.flipResultText}>{data.toUpperCase()}</Text> } </View>
Now when we hit the Flip Coin button, the image flips, and an API request is sent to the Coin Flip API. The response is then saved to the data
variable and displayed in the app!
Conclusion
There is a lot of opportunity with React Native and still much room for the project to grow. That makes it an exciting step for a developer. At the same time, there can be a series of troubleshooting steps and configurations that need to be taken care of before developing a larger project.
Our application utilized Expo, which is the fastest way to start developing an application. However, if you were going to spend a significant amount of time in React Native it’s probably best to get the iOS and Android simulators set up on your local machine.
I hope that this application has taken you into exciting new territory! If you have any questions or comments please leave a comment below!
Related FAQ
Companies that use React Native in their Apps
Top companies that have used React Native in their apps include:
- Bloomberg
- Airbnb
- Gyroscope
- Myntra
- UberEats
- Discord
What are some alternatives to create a react native app?
If you’re looking for some alternatives to use instead of react native, here are a few that might interest you:
- Bootstrap
- Flutter
- PhoneGap
- Apache Cordova
- Ionic Framework
- NW.js
How much does create react native app cost?
React Native framework is one of the most cost-effective frameworks present in the market. If you are on a tight budget and want to have an app, then the React Native is the best option.
React Native development cost varies depending upon the complexity of the apps and the requirement.
Monish Sinthala says
Wow, what an article. Kudos Jared. Step by step info on React native App tutorials. Btw will share it to my peers, good work and keep going.