Building Cross-Platform Mobile Apps with React Native

Akanle DolapoAkanle Dolapo
8 min read

Introduction

Imagine you are working on a new app idea. You want everyone to use it, whether on an iPhone or an Android phone. However, writing two completely different versions of the same app is not ideal. This is where cross-platform mobile apps come in. They allow you to write one codebase that runs on multiple platforms, saving you time and effort. In this article, I will discuss the process of building cross-platform mobile apps with React Native.

What is React Native?

React Native is a framework developed by Facebook that allows you to build mobile apps using JavaScript and React. Instead of writing separate code for iOS and Android, React Native lets you use a single codebase to create apps that work on both platforms. This not only speeds up development but also ensures a consistent user experience across different devices.

Setting Up the Development Environment

Before you can start building with React Native, you must set up your development environment. Don’t worry, this part is straightforward, and I’ll walk you through each step. You’ll need Node.js, npm, React Native CLI, and development tools like Xcode (for macOS users) and Android Studio. Follow these steps carefully, and you’ll be ready to dive into React Native development in no time.

  1. Node.js and npm: Make sure you have Node.js installed. npm (Node Package Manager) comes bundled with it.

  2. React Native CLI: Install the React Native command-line interface.

npm install -g react-native-cli

This command installs the React Native CLI globally on your machine, allowing you to create and manage React Native projects from the terminal.

  1. Xcode (for macOS users) and Android Studio: These tools are necessary for building and testing your app on iOS and Android, respectively.

Follow these steps to set up your environment:

  1. Install Node.js from nodejs.org

  2. Install the React Native CLI.

  3. Install Xcode from the Mac App Store and Android Studio from the Android developer site.

Using Expo for Quick Development

Expo is a set of tools, libraries, and services that simplify the development of React Native applications. It provides a managed workflow that abstracts away much of the complexity, allowing you to focus on building your app.

  1. Install Expo-CLI:
npm install -g expo-cli

This command installs the Expo CLI globally on your system, allowing you to create and manage Expo projects.

  1. Create a New Expo Project:
expo init MyNewApp

Follow the prompts to choose a template. The blank template is a good starting point.

  1. Navigate to Your Project Directory and Start the Development Server:
cd MyNewApp
expo start

This command starts the Expo development server. You can open the app on your physical device using the Expo Go app, or on an emulator/simulator.

  1. Run Your App:

    • Scan the QR code displayed in the terminal using the Expo Go app.

    • Or, press 'i' to open the iOS simulator or 'a' to open the Android emulator if they are set up.

Creating Your First React Native App

Now that your environment is set up, it’s time to create your first React Native app. This is where things get exciting! This section will guide you through initializing a new project and running a basic application.

To create a new React Native project, open your terminal and run:

npx react-native init MyNewApp

This command initializes a new React Native project named "MyNewApp".

Navigate to your project directory and start the development server.

cd MyNewApp
npx react-native start

These commands navigate to your project directory and start the Metro Bundler, which serves your React Native app.

To run the app on an iOS simulator or an Android emulator, open a new terminal and run:

npx react-native run-ios
# or
npx react-native run-android

These commands build and launch your app on an iOS simulator or Android emulator, respectively. You should see your first React Native app running with a simple “Hello, World!”.

Core Concepts and Components

Understanding the core concepts and components of React Native is essential for building apps. In this section, we’ll explore the basics, including JSX, components, state, and props. These foundational elements are key to creating and managing user interfaces in React Native. By the end, you'll have a solid grasp of how these building blocks fit together to create your app’s UI.

React Native combines the best parts of native development with React, a best-in-class JavaScript library for building user interfaces. Let’s break down some core concepts:

  • JSX: A syntax extension for JavaScript, used with React to describe what the UI should look like.

  • Components: The building blocks of a React Native app. You create small, reusable pieces like <View>, <Text>, and <Image> to build your UI.

  • State and Props: Mechanisms for managing data in your app. State is used for data that changes over time, while props are used to pass data from parent to child components.

Example of a simple component:

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

const HelloWorld = () => (
  <View>
    <Text>Hello, World!</Text>
  </View>
);

export default HelloWorld;

In this example, HelloWorld is a functional component that returns a View containing a Text element displaying "Hello, World!". import statements bring in necessary modules from React and React Native.
See the result in the image below:

Styling in React Native

Styling your app is just as important as building its functionality. I’ll show you how to apply styles in React Native, which is quite similar to CSS but uses a JavaScript object syntax known as StyleSheet . See the example below:

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

const App = () => (
  <View style={styles.container}>
    <View style={styles.textWrapper}>
      <Text style={styles.text}>Welcome to my App!</Text>
    </View>
  </View>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
     justifyContent: 'center',
     alignItems: 'center',
   },
   textWrapper: {
     backgroundColor: '#72063c',
     padding: 14,
     borderRadius: 12
   },
   text: {
     fontSize: 40,
     color: '#ffff',
   },
});

export default App;

Here, the App component uses a View and Text element, styled using the StyleSheet object. styles.container centers the content, styles.textwrapper sets the background color, padding, and border-radius and styles.text sets the font size and color of the text. See the result in the image below;

Handling Navigation

Navigation is a crucial part of any mobile app. It’s how users move from one screen to another. Here, we'll be discussing the React Navigation library, a comprehensive solution for managing navigation in your React Native apps. We’ll also set up basic stack navigation to show you how you can add smooth and intuitive navigation to your app.

Install the library:

npm install @react-navigation/native
npm install @react-navigation/stack

These commands install the core navigation library and the stack navigator.

Setup basic Navigation:

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { View, Text, Button } from 'react-native';

const HomeScreen = ({ navigation }) => (
  <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
    <Text>Welcome to my App!</Text>
    <Button
      title="Get started"
      onPress={() => navigation.navigate('Details')}
    />
  </View>
);

const DetailsScreen = () => (
  <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
    <Text>Details Screen</Text>
  </View>
);

const Stack = createStackNavigator();

const App = () => (
  <NavigationContainer>
    <Stack.Navigator>
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen name="Details" component={DetailsScreen} />
    </Stack.Navigator>
  </NavigationContainer>
);

export default App;

In this example, we set up a stack navigator with two screens: HomeScreen and DetailsScreen. HomeScreen displays a simple message and a button that navigates to the DetailsScreen which also displays a simple message indicating it's the details screen. NavigationContainer manages the navigation state, and Stack.Navigator handles the stack-based navigation.

This image displays the HomeScreen;

This image shows the Details Screen;

State Management

Managing state in complex React Native apps is crucial for keeping data organized and ensuring your UI reflects changes accurately. Popular state management options include Redux and the Context API, which help maintain a consistent state throughout your app. Here’s how you can implement state management using the Context API.

Using Context API:

import React, { createContext, useState } from 'react';

export const AppContext = createContext();

const AppProvider = ({ children }) => {
  const [state, setState] = useState('Hello, World!');

  return (
    <AppContext.Provider value={{ state, setState }}>
      {children}
    </AppContext.Provider>
  );
};

export default AppProvider;

This example sets up a context for state management. AppContext is created using createContext(), and AppProvider is a component that uses useState to manage a piece of state and provide it to its children via AppContext.Provider. The AppContext and useState are used to create a global state (state) that can be accessed and updated across different screens to make data management seamless.

Working with APIs and Data

Fetching and displaying data from APIs is a common requirement for most apps. This section covers how to use libraries like fetch or axios to retrieve data and display it within your React Native app, enabling you to integrate external data sources into your application smoothly.

Example using fetch:

import React, { useEffect, useState } from 'react';
import { FlatList, Text, View, StyleSheet } from 'react-native';

const App = () => {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(data => setData(data.slice(0, 5))); 
  }, []);

  return (
    <View style={styles.container}>
      <FlatList
        data={data}
        keyExtractor={(item) => item.id.toString()}
        renderItem={({ item }) => (
          <View style={styles.itemContainer}>
            <Text style={styles.title}>{item.title}</Text>
          </View>
        )}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f0f0f0',
    padding: 10,
  },
  itemContainer: {
    backgroundColor: '#fff',
    padding: 15,
    marginVertical: 8,
    borderRadius: 10,
  },
  title: {
    fontSize: 18,
    color: '#333',
  },
});

export default App;

In this example, we use the useState hook to store the fetched data and the useEffect hook fetches data from an API when the component mounts. The data is then displayed using a FlatList, which renders each item within a View containing a Text component to show the title. The slice(0, 5) method is applied after fetching the data to limit the display to the first five items as seen in the image below:

Conclusion

Congratulations! You've successfully built and tested your first React Native app. This article has guided you through the essential steps of mobile app development, from setting up your environment to deploying your app on both iOS and Android platforms. Remember, the key to successful app development is continuous learning and iteration. Keep exploring new features, optimizing performance, and gathering feedback from users to make your app even better. Happy coding!

Additional Resources

React Native docs

React Navigation

24
Subscribe to my newsletter

Read articles from Akanle Dolapo directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Akanle Dolapo
Akanle Dolapo