Skip to content

Latest commit

 

History

History

07.Expo

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

Workshop 7 - Mobile app with Expo

✔️ Learn the basics of React Native

✔️ Discover Expo to easily develop a mobile app

✔️ Explore mobile-specific features with the camera

In this workshop, we will create a simple mobile in written in React Native with TypeScript. When working with mobile apps, you often need to build your app, have xcode or android studio launched, your device plugged, your ram almost full, struggling with permissions and compilations errors because of unsupported model or update etc.

Expo is here to simplify all this laborious work. No wire, no android studio, no version errors, just a QR code to scan and the app is locally built and sent to the expo client on your phone. Way easier!

Step 0: Initialization

All the required information to install dependencies can be found in SETUP.md.

Step 0.5: Information

As written in the name, react native is based on React, a very popular front-end framework to create websites. components are the core of React. They represent a single element in a web page, like a text box, a button, a div, etc. All combined, they create a fully working web page. These components are reusable, they prevent you from code duplication. This also works in React Native, component won't be web elements but will create native mobile components.

In this workshop, you are not allowed to use TypeScript classes, you must use Functional Components. Here is a little explanation of the differences.

Now that it's clear, time to work! The template repo is quite large, so let's discover it. There are files that we won't use but also useful stuff. Please find:

  • Where is the higher component of the app (the one that calls all the others)

  • What is the background color of the dark theme used by expo

  • Which function opens the web browser on the Tab One screen

  • What is the main navigator and what is the navigator describing the bottom bar

Step 1: Basic todolist

Now that you understand a bit more the architecture of the project, let's create something! First off, wipe everything inside the TabOneScreen.tsx file: we will create a simple todolist component.

The goal of the workshop of not to learn how to code in React but rather learn how to use React Native, so we won't waste time on creating basic components. Here is a Task component, copy everything inside your empty file:

import * as React from 'react';
import { ScrollView } from 'react-native';
import { Text, View } from '../components/Themed';

function Task(props: {title: string, completed: boolean}) {
  return (
    <View style={{ width: "90%", flexDirection: "row" }}>
        <Text style={{ fontSize: 16, marginRight: 10, color: props.completed ? "green" : "red" }}>
          {props.completed ? "DONE" : "TODO"}
        </Text>
        <Text style={{ fontSize: 16 }}>
          {props.title}
        </Text>
    </View>
  );
}

export default function TabOneScreen() {
  return (
    <ScrollView style={{ flex: 1 }}>
      <Task title="Start workshop" completed={false} />
    </ScrollView>
  );
}

Your goal in this task will be to edit this code to display a new List component. To do so, you will have an Array of objects:

function List() {
    const [taskList, setTaskList] = React.useState(["finish step 2", "finish step 3"]);
    return (...)
}

Some precisions:

  • React Native uses different components of React, here is the documentation

  • By default, all task completed props will be set to false

  • taskList is a const variable that can only be changed by the function setTaskList associated with it

  • taskList is an array of objects with currently only 2 indexes in the example

  • Each index of the array represents the variable that will be sent to the Task component

The map function will be very useful to iterate over our array

Step 2: Online loading

Now that we dynamically display our tasks in a single component that loops over data, let's fetch this data online rather than just writing some!

Add this block of code after your imports:

import axios from 'axios'

type TodoDto = {
    userId: number;
    id: number;
    title: string;
    completed: boolean;
}

async function getTasks(): Promise<TodoDto[]> {
    const ret = await axios.get("https://jsonplaceholder.typicode.com/todos")
    console.log(ret.data)
    return ret.data
}

and call getTasks on your list component (before the return), this should print in the terminal a JSON object representing a list of tasks. The goal of this step is to replace the hard-coded values in your taskList array with these fetched values.

  • Don't forget to use the completed variable
  • The data fetching is asynchronous, you won't have data while it's loading, so taskList will be called with React.useState<TodoDto[] | null>(null);
  • You'll need the useEffect hook to execute actions when the component is created (here, the action will be to load data)

Step 3: QR code scanning

Now that we've seen the basic features that react and React Native can offer, let's do something totally different, time to create a screen that will display a camera and have the ability to scan QR code. The URL encoded in the code will be opened in a web browser on success.

First off, you'll have to install new packages:

# Stop your server and run
npx expo install expo-camera expo-barcode-scanner expo-media-library

# Then restart your server
npm start

Here is the Camera documentation, there are useful examples, search for code scanning

You can do this in the file TabTwoScreen.tsx 😉

  • handleBarCodeScanned arguments type are { type: string; data: string } (but you may only need data 😉)
  • If the QR code struggles, do not hesitate to reload the app (shake your device to trigger the option panel)

You can use this QR code as an example:

Step 4: Take a picture and flip

Our camera works great, but we cannot even do basic stuff such as taking pictures or using the front camera... That's why your last task will be to add those features to your screen, add:

  • A flip button that changes the camera type from front to back and vice versa
  • A trigger button that will take a picture and save it to the camera roll

You'll need to use React refs to take a picture Your IDE might show an error when using the ref attribute, you can ignore it as it shouldn't block the compilation

Bonus

Here is a list of possible features you could add to your project

Easy

  • Add styles to your todolist! Use some CSS
  • Add a pull to refresh option to your ScrollViews
  • Use a Flatlist instead of a ScrollView to have the ability to load data when the end is reached (and also have the ability to pull to refresh)

Medium

  • Add new pages to the bottom tab navigation
  • Create a button that navigates to another screen when pressed: navigation.navigate("SCREEN_NAME")
  • Try changing the bottom tab navigation icons

Hard

  • Create an Authentication process with a context:
    • Create another navigator with a single screen: the app landing screen
    • Set this navigator as default when the app is opened (just put it before Root navigator)
    • On the landing screen, add a button that will fake our login, when press, we will consider that we are logged in
    • Setup a context to save if the user is logged in. Everything is explained here
    • Set the userToken state of the context to poc when the button is pressed, this should switch to another screen

Authors


Paul Monnery

Organization


LinkedIn logo Instagram logo Twitter logo Discord logo

Website logo

🚀 Don't hesitate to follow us on our different networks, and put a star 🌟 on PoC's repositories.