Building Mobile Apps with React Native

Building Mobile Apps with React Native

In this tutorial, we'll learn how to build mobile apps with opensource React Native. We'll see by example how to build a mobile applications, step by step, that fetches and displays news articles from a third-party REST API.

In this tutorial, we'll be building a news application to help you learn about the basics of React Native development process. Our mobile app will be cross-platform which means it can be used on both Android apps and iOS. We'll be using Expo for development which will allow us to initialize a new project and easily test it in a real mobile device.

Tip
If you are a beginner in React native web development, make sure to check out our React Cheat Sheet article for some entry-level time saving tips and tricks that will be helpful in your journey. image.png

What is React Native?

React Native is an open source SDK for building native mobile applications using JavaScript. It's based on React, a popular front-end library for building user interfaces using composable components created by Facebook.

Unlike the popular hybrid frameworks such as Ionic, React Native doesn't use a webview which means your mobile application is not a web application that has access to native device features like the case of Ionic but a native app that uses native components in both Android apps and iOS.

React Native is essentially a bridge that allows your JavaScript app to access native device features and user interface components.

Tip
You can use Buddy to build your React Native apps and speed up your development process. Learn more about our actions.

Prerequisites

In this tutorial, we'll develop a mobile application from scratch using JavaScript and React Native so you'll need to have a few prerequisites before you can comfortably proceed with the next steps:

  • Node.js and NPM installed on your system. You can install both of them from the downloads page of the official website. You can also refer to your system docs for the specific instructions on how to install Node on your system. A better way is to use NVM that allows you to install and manage multiple versions.
  • Familiarity with JavaScript,
  • Working knowledge of React and familiarity with the basic concepts like components, hooks, props, and state, etc.

You'll also need to register a free account with NewsAPI.org and note the API key.

News API is a simple and easy-to-use API that returns JSON metadata for headlines and articles live all over the web.

If you have the previous prerequisites, you are ready for the next steps of this tutorial.

Installing Expo CLI

Expo CLI is a command-line utility that allows you to use Expo tools. You can use it to create a new React Native project, develop and test your mobile app, build and publish your app to the App and Play Stores, etc.

Let's now install the Expo CLI. Open a new command-line interface and run the following command:

bash
$ npm install -g expo-cli $$

Note: Please note that you may need to use sudo before your command in Linux or macOS to install npm packages globally or use a CMD with administrator access on Windows. if you get any EACCESS permission errors you can also just fix your npm permissions.

Wait for npm to install the CLI and let's proceed to the next step.

Creating a React Native Project

After installing the Expo CLI, let's use it to initialize our React Native project. Head back to your command-line interface and run the following command:

bash
$ expo init react-native-example $$

You'll be asked to choose a template for your project, use the blank template and type a name for your application then wait for the CLI to generate the necessary files and install the packages from npm.

Next, navigate to your project's folder and run the local development server using the following commands:

bash
$ cd react-native-example $ expo start $$$

This is a screenshot below of what you'll get in your terminal. The command starts the Metro bundler which bundles the JavaScript code of your application and Expo DevTools that allows you to debug your application. Depending on your development environment, you can either use an iOS simulator or an Android emulator or an actual mobile device to test your application. If you don't have a development environment with Java and Android Studio installed or a macOS with Xcode you can install the Expo app on your mobile device and scan the QR code as shown:

Image loading...Creating a React Native apps project

Go ahead and install the Expo app on your mobile device and scan the QR code in your terminal, you should be able to start your app on your mobile device. This is a screenshot:

Image loading...Starting your app on your mobile device

Next, open the App.js file, you should find the following code that is responsible for rendering the user interface in the previous screenshot:

jsx
import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; export default function App() { return ( <View style={styles.container}> <Text>Open up App.js to start working on your app!</Text> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });

We import React from react, next we import StyleSheet, View and Text UI components from react-native.

Next, we define and export a functional React component. This function returns the JSX code that renders the UI of our screen. JSX is an extension for JavaScript that allows you to write an XML-like markup in JavaScript.

The View and Text components are basic UI components for React Native apps. You can think of them as the <div> and <p> tags in HTML.

View is a fundamental React Native component for creating a UI. It’s simply a container which is equivalent to a native view such as UIView in iOS, android.view in Android, or <div> in HTML. View has support for the Flexbox layout by default, and supports styles and touch events.

Inside the View component, we have a Text component which wraps the Open up App.js to start working on your app! text. When building React Native apps, you should always wrap the text with the Text component which also supports styles and touch events.

React Native makes use of CSS written in JavaScript where CSS properties are defined using the camelCase. For example, we use backgroundColor instead of background-color.

All React Native components support a style prop that you can use to assign styles to the component using either an inline JavaScript object or a reference to an object that encapsulates the styles.

You can define styles in plain JavaScript objects and you can also use the StyleSheet API, provided by React Native, that enables you to define and manage multiple styles.

In our example code, we used the StyleSheet.create() method to define reusable styles and we referenced them from the JSX code:

jsx
const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });

We create a container object that contains the desired styles then assigned the styles to View using the style prop:

jsx
<View style={styles.container}> </View>
Tip
Always make sure to check React Native development blog for new features

Adding Multiple Screens in our Application

Now that we have explained the basics of React Native, let's modify our example code to create our application.

In this section, we'll see how to use conditional rendering to create multiple views or screens.

Please note that for complex scenarios, you'll need to use advanced navigation systems such as React Native Navigation library but in our case, since we'll only have two views in our application, we can use conditional rendering for implementing multiple screens.

Let's head to the App.js file and define a Home() component as follows:

jsx
const Home = () => { return ( <View style={styles.container}> <Text> This will be the home screen of our application. </Text> </View> ); }

Next, define a Loading component as follows:

jsx
const Loading = () => { return ( <View style={styles.container}> <Text> Loading... </Text> </View> ); }

Next, change the App() component as follows:

jsx
export default function App() { const [fetchingData, setFetchingDataState ] = React.useState(true); setTimeout(() =>{ setFetchingDataState(false); } , 1000); if (fetchingData){ return <Loading /> } else { return <Home /> } }

We use the useState() hook to create a fetchingData state variable that takes a boolean value and a setFetchingDataState() method to update the value of the state variable.

The fetchingData state variable has a first value of true which means the <Loading /> component will be rendered first. After one second, the value of fetchingData will be changed to false via the setFetchingDataState() method which will make the <Loading /> component to disappear and the <Home /> component will be rendered.

You can now go back to your mobile device and see these works. You don't need to restart your application since the development server will live-reload your app when you do any changes in the code.

This is a screenshot of the loading screen:

Image loading...Screenshot of the loading screen

And this is a screenshot of the home screen:

Image loading... Screenshot of the home screen

Now if that works, let's see how to actually fetch news data from a third-party REST API.

How to Fetch Data in React Native

After seeing how to change between two screen views after an amount of time, let’s see how we can fetch data from a REST API. When data fetching is done we can then render the home screen.

React Native provides the Fetch API that allows you to consume REST APIs or fetch data from web servers.

In our <Loading> component, we need to use the useEffect hook to perform a side effect. In our case, it's fetching data from a REST API server.

Head back to the App.js file and add the API_KEY and apiUrl variables as follows:

jsx
export default function App() { const API_KEY = "<PUT_YOUR_API_KEY>"; const apiUrl= `https://newsapi.org/v2/everything?q=comics&sortBy=publishedAt&apiKey=${API_KEY}`;

Note: Make sure to replace <PUT_YOUR_API_KEY> with your own API key from the News API.

Next, add the items state variable for storing the news articles and initialize it with an empty array using the useState() hook:

jsx
export default function App() { const API_KEY = "<PUT_YOUR_API_KEY>"; const apiUrl = `https://newsapi.org/v2/everything?q=comics&sortBy=publishedAt&apiKey=${API_KEY}`; const [items, setItems] = React.useState([]);

Next, call the fetch() method in the useEffect() hook to fetch data from the news API as follows:

jsx
export default function App() { const API_KEY = "<PUT_YOUR_API_KEY>"; const apiUrl = `https://newsapi.org/v2/everything?q=comics&sortBy=publishedAt&apiKey=${API_KEY}`; const [fetchingData, setFetchingDataState] = React.useState(true); const [items, setItems] = React.useState([]); React.useEffect(() => { fetch(apiUrl) .then((response) => response.json()) .then((data) => { return data.articles; }) .then(articles => { setItems(articles); setFetchingDataState(false); }) .catch(error => { console.error(error); }); }, []);

Now, let's pass the fetched articles to the <Home> component using a data property as follows:

jsx
if (fetchingData){ return <Loading /> } else { return <Home data = { items }/> }

We have fetched data from the REST API and passed it to the home component, let's now modify the component to enable it to render the passed data via the data prop. Change the Home function as follows

jsx
const Home = ({data}) => { return ( <View> { data.map((item, index)=>{ return <Text key = {index}> { item.title } </Text> }) } </View> ); }

Inside the <View> container, we call the JS map() method to iterate over the data array and display the title of each news article using a Text component.

You can now head to your mobile phone to see your news data displayed before we further develop our app by using the FlatList component to render the list of articles:

Image loading...News data displayed

Using FlatList in React Native

React Native provides FlatList and SectionList for efficently rendering and working with lists.

Let's change our component to use a FlastList.

Head back to the App.js file and import the FlatList component as follows:

js
import { StyleSheet, Text, View, FlatList } from 'react-native';

Next, change the Home() component as follows:

js
const Home = ({data}) => { return ( <View style={styles.container}> <FlatList keyExtractor={(item, index) => index.toString()} data={ data } renderItem={({item}) => <Text> {item.title}</Text>} /> </View> ); }

Instead of rendering the title of the news article only, let's display other information like the description, URL and image. In the App.js file, add the following function:

js
const Item = ({ data }) => { return ( <View style={styles.itemContainer}> <Image style={styles.itemImage} source={{ uri: data.urlToImage }} /> <Text style={styles.itemTitle}> {data.title} </Text> <Text style={styles.itemDescription}> {data.description} </Text> <View style={styles.itemBtn}> <Button onPress={() => { console.log("Button pressed!") }} title="Read" /> </View> </View> ) }

Make sure you import Image and Button:

js
import { Image, Button } from 'react-native';

Next, modify the Home() component as follows:

js
const Home = ({ data }) => { return ( <View style={styles.container}> <FlatList keyExtractor={(item, index) => index.toString()} data={data} renderItem={({ item }) => <Item data={item} />} /> </View> ); }

Next, we need to add the following styles to the styles object:

js
const styles = StyleSheet.create({ /* [...] */ itemContainer:{ borderWidth: 0, width: '100%', padding: 5 }, itemimage: draft: yes { height: 200 }, itemTitle:{ textAlign: "center", padding: 20, fontSize: 17, color: 'black', backgroundColor: 'white', }, itemDescription:{ fontSize: 17, padding: 10, color: 'black', backgroundColor: 'white', }, itemBtn:{ flexDirection: 'row', backgroundColor: 'white', } }

This is a screenshot of our application at this point:

Image loading...Styling our app

Now that we have created and styled the UI of our application, let's head to the next section.

Opening External URLs in React Native

During our development process we have added a button to enable users to open the news articles using a web browser for reading the full articles. Let's now see how to actually implement the button functionality.

Head to the App.js file and import Linking as follows:

js
import { Linking } from 'react-native';

Next, define the following method:

js
const readFullArticle = (url) => { Linking.openURL(url).catch((err) => console.error('An error occurred', err)); }

We simply call the openURL() method of Linking to open a URL in the default web browser of the mobile device.

Finally, you need to call this method in the Item component as follows:

js
const Item = ({ data }) => { return ( <View style={styles.itemContainer}> <Image style={styles.itemImage} source={{ uri: data.urlToImage }} /> <Text style={styles.itemTitle}> {data.title} </Text> <Text style={styles.itemDescription}> {data.description} </Text> <View style={styles.itemBtn}> <Button onPress={() => { readFullArticle(data.url); }} title="Read" /> </View> </View> ) }

Head back to your mobile device. You should be able to open the full article in the web browser.

You can read the docs for more information about what you can do with Linking which allows you to interact with incoming and outgoing application links.

Conclusion

In this tutorial, we've introduced React Native and built a mobile application for Android and iOS from scratch using JavaScript and Expo CLI.

You can find the source code from this GitHub repository.

Read similar articles