Mobiele apps bouwen met React Native

Heb je al een tijdje een eigen website? Grote kans dat je dan ook wel eens hebt nagedacht of je aanvullend een eigen app wil aanbieden. Door de komst van responsive design is het gat tussen desktop en mobiel voor websites natuurlijk een heel stuk kleiner geworden. Toch voelt een échte app qua performance en integratie met Android of iOS vaak prettiger in gebruik. Lees daarom hoe je mobiele apps bouwt met React Native!

Mobiele apps bouwen met React Native!

Het is nogal een stap om vanuit een achtergrond met webdevelopment met een eerste mobiele app te beginnen. Het aanleren van Java of Swift, het installeren van de SDK’s en emulators, en de configuratie en signing van je applicatie is een hoop gedoe. Gelukkig biedt React Native in combinatie met Expo een laagdrempelig alternatief. Hiermee bouw je een native app alsof je een moderne JavaScript-webapplicatie bouwt. Deze kun je vervolgens zonder moeite testen op je eigen smartphone.

Wat is React Native?

React Native is een op React-gebaseerde technologie van Facebook en één van de drie populairste JavaScript frameworks van dit moment. Met React Native kun je in modern JavaScript een app programmeren die vervolgens wordt omgezet naar een native app voor Android of iOS. Het is dus geen wrapper om je website heen, zoals Phonegap, maar een echte mobiele applicatie.

Het idee van React Native is overigens niet dat je in één keer een app bouwt voor zowel Android en iOS. Daarvoor zijn de platforms te verschillend en wil je waarschijnlijk gebruikmaken van te specifieke componenten voor beide systemen. De filosofie is dat je slechts één keer deze techniek hoeft te leren en dat het bouwen van een app voor Android en iOS dan allebei goed te doen is.

Wat is Expo?

Het omzetten van een React Native-project naar een native app voor het mobiele platform introduceert normaal gesproken technische rompslomp. Daar ben je liever niet mee bezig. Je hoeft dan wel geen Java, Swift of Objective C te leren, maar het converteren, configureren en ondertekenen van de app, kost alsnog een hoop moeite.

Expo biedt een app, waarmee je de code die je op je computer bouwt heel simpel naar je smartphone overbrengt. Je installeert de Expo app, scant de QR-code die voor je app van je PC wordt gegenereerd en je kunt direct beginnen met testen.

Hup, publiceren maar!?
Merk op dat voor daadwerkelijke publicatie in de Google Play Store of de App Store extra werk vereist is voor de conversie en het signen van de applicatie. Voor nu kunnen we echter eenvoudig beginnen.

Installatie van de basisbenodigdheden

Het helpt voor deze introductie als je al een beetje een achtergrond hebt in ontwikkeling met behulp van JavaScript frameworks en als je je weg kent in de commandline van je systeem. De instructies zijn getest op een Linux machine in combinatie met Android, maar zouden met minimale aanpassingen ook op Mac of Windows moeten kunnen worden gebruikt.

We beginnen met de installatie van een recente versie van Node.js. Dit is een JavaScript runtime op basis van Google Chrome, waarin je je applicatie kunt laten draaien. Als je wenst, kun je dit uitbreiden met aanvullende pakketten, zoals React Native.

Na installatie van Node.js kun je met npm de installatie van expo-cli voltooien. Dit is de Expo software die het opzetten en het testen van je app een stuk eenvoudiger maakt. Draai voor de installatie het volgende commando als superuser/root:

npm install -g expo-cli

Het aanmaken en opstarten van je app

Nu Expo beschikbaar is, beginnen we met de initialisatie van een nieuwe app.

expo init MijnEersteApp
De initialisatie van een nieuwe applicatie.

Wacht tot deze initialisatie is afgerond en start je applicatie met de volgende commando’s. Dit opent een webpagina met daarop een QR-code.

cd MijnEersteApp
expo start

 

Voorbeeld van een Expo-pagina met QR-code.

Verbinden met je telefoon

De QR-code kun je met de mobiele app van Expo scannen. Die is beschikbaar in de App Store en Google Play Store. Het is niet nodig om bij Expo een account aan te maken om verder te kunnen gaan. Scan de QR-code door in de Expo app naar Projects te navigeren (de vier blokjes links onderin het scherm) en selecteer Scan QR Code.

Expo: QR-code scannen.

Ging alles goed? Mooi! Dan zie je nu voor het eerst de basis van je app live op je smartphone.

Een basis React-app.

Lukt het niet om te verbinden of de app te laden? Controleer het volgende.

  • Je smartphone moet verbonden zijn met hetzelfde wifi-netwerk als je computer.
  • Links onderin op de webpagina moet LAN als connectiemethode staan geselecteerd.
  • Soms zorgt een syntax-fout ervoor dat Expo even van de wijs is en niets meer wil laden. Expo op de PC opnieuw opstarten, lost dit probleem op.
  • De poort voor de Expo-server moet bereikbaar zijn vanaf je telefoon. Je ziet deze poort op de webpagina staan. Op Ubuntu Linux kun je deze beschikbaar maken met: ufw allow 19001/tcp

Minicursus apps bouwen

De minicursus kan nu beginnen! We kijken onder andere naar App.js, de navigatie en projectstructuur.


Is dit voor jou allemaal gesneden koek en heb jij deze uitleg niet nodig? Keurig. Heb je daarnaast ervaring met Python en Django? Nog beter! We zoeken jou. Bekijk onze vacature en kom eens op de koffie. 

Bekijk de vacature →


Structuur van het project

De initialisatie van Expo heeft een aantal bestanden en mappen aangemaakt in je projectmap:

De projectstructuur van je mobiele app.

Het bestand app.json bevat de projectconfiguratie, zoals de naam en de versie van de app. De bestanden package.json en package-lock.json registreren welke pakketten zijn geïnstalleerd met npm, deze staan in de map node_modules. In de map assets staan de afbeeldingen van de app, voor nu een standaardlogo en laadscherm.

App.js

Voor ons is nu het meest interessante bestand App.js. Dit is de functionele code, dus open deze snel om je eigen welkomstgroet te tonen.

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

export default function App() {
  return (
    
      Open up App.js to start working on your app!
    
  );
}

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

Je ziet dat het bestand App.js uit een paar onderdelen is opgebouwd. Mogelijk komt het bekend voor als je al eerder met JavaScript hebt gewerkt. De App()-functie wordt aangeroepen bij het starten van de app.

Merk op dat deze functie geen HTML teruggeeft, maar JSX. De componenten Text en View die daarin worden gebruikt, zijn aan het begin van het bestand geïmporteerd uit de React Native library. Op je je smartphone worden deze direct omgezet in de corresponderende elementen uit Android of iOS.

Het stylesheet onderaan het bestand lijkt wat op CSS, maar heeft een afwijkende naamgeving en een wat beperkter aanbod aan mogelijkheden. Zie voor alle beschikbare eigenschappen het overzicht van React Native. Let op: sommige componenten zoals knoppen hebben een vaste styling en kunnen niet worden aangepast.

Standaardtekst aanpassen in je mobiele app.

Heb je de app nog open staan zoals bij ‘Verbinden met je telefoon’ staat beschreven? Vervang de standaardtekst ‘Open up App.js to start working on your app!’ door je eigen tekst. De app wordt automatisch opnieuw geladen en na een paar seconden zie je de nieuwe tekst verschijnen. Gefeliciteerd! Je hebt je eerste stap gezet in app development.

Componenten en Props

De code in App.js is nu nog kort en vrij overzichtelijk, maar zodra je app groter en complexer wordt, wordt het onhandig om alles in die ene App()-functie te blijven toevoegen.

Componenten zijn binnen React Native dé manier om je applicatie op te knippen in kleinere en makkelijk herbruikbare onderdelen. Je kunt bestaande componenten uit React Native gebruiken, zoals View of Text, maar je kunt ook zelf nieuwe componenten aanmaken. Soms hebben deze componenten informatie nodig om goed te kunnen werken, dit kun je dan meegeven in props. De waarde style die aan component View wordt doorgegeven, is een voorbeeld van zo’n prop.

Je ziet hieronder hoe je in App.js het Greeting-component toevoegt met de prop name en deze aanroept vanuit de App()-functie.

...
class Greeting extends Component {
    render() {
        return (
            <View>
                <Text>Hallo {this.props.name}!</Text>
            </View>
        );
    }
}

export default function App() {
  return (
    <View style={styles.container}>
      <Greeting name='wereld'/>
    </View>
  );
}
...

De render()-functie in ‘Greeting’ is vergelijkbaar met de App()-functie. Het is het aanspreekpunt van je component en tevens de functie die de JSX teruggeeft.

Knoppen en navigatie

Een app bestaat zelden uit slechts één scherm. We gaan daarom de app nu uitbreiden met de mogelijkheid om te wisselen tussen meerdere schermen. Voor we verder gaan met navigatie in onze app toevoegen, hebben we een paar aanvullende pakketten nodig. Deze installeer je met:

expo install react-native-gesture-handler react-navigation react-native-screens react-navigation-stack

Vervang de code van App.js met de opzet van de nieuwe navigatie:

import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import HomeScreen from './screens/HomeScreen';
const MainNavigator = createStackNavigator({
  Home: {screen: HomeScreen},
});

const App = createAppContainer(MainNavigator); 

export default App;

Maak vervolgens in je project een nieuwe map aan voor de schermen van je app, met de naam screens. Begin daarin met het startscherm. Hiervoor maak je een nieuw bestand aan met de naam HomeScreen.js en de volgende inhoud:

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

export default class HomeScreen extends Component {
    static navigationOptions = {
        title: 'Startscherm',
    };

    render() {
        return (
            <View style={styles.container}>
                <Button title="Open wikischerm"
                        onPress={() => this.props.navigation.navigate(‘Wiki’)}
                />
            </View>
        );
    }
}

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

Het nieuwe component HomeScreen.js lijkt behoorlijk op de oorspronkelijke code van App.js. Er zijn wel wezenlijk verschillen. Om te kunnen navigeren, hebben we de configuratie navigationOptions toegevoegd met daarin de titel van het scherm.

Verder hebben we onze groet vervangen door een Button-component. We kunnen die zodalijk gebruiken om naar een nieuw scherm te navigeren. De onPress-prop bevat code die wordt uitgevoerd als je op de knop drukt. In dit geval is dat de navigate()-functie, die door het navigatieframework standaard wordt meegegeven in de props van alle schermen.

Navigatie in je Reacte Native-app.

Als je op de knop drukt gebeurt er nu nog niets, dat komt omdat het scherm ‘Wiki’ nog niet bestaat. Dit voegen we toe in het volgende onderdeel.

Invoervelden en state

Tot nu toe hebben we tekst op een scherm getoond en navigatie toegevoegd. Om echt nuttige functionaliteit te kunnen bieden, hebben we invoer van de gebruiker nodig. In dit onderdeel kijken we naar de manier waarop een gebruiker tekst kan invoeren en hoe de app deze invoer in het component kan bewaren. We doen dit in een nieuw scherm. Voeg dit toe als het bestand WikiScreen.js in de map screens:

import React, { Component } from 'react';
import { Button, Keyboard, StyleSheet, Text, TextInput, View } from 'react-native';

const styles = StyleSheet.create({
    container: {
        padding: 16,
    },
    search: {
        fontSize: 16,
        borderBottomWidth: 1,
        borderColor: '#CCCCCC',
        marginBottom: 20,
    },
});

export default class WikiScreen extends Component {
    static navigationOptions = {
        title: 'Wikischerm',
    };

    constructor(props) {
        super(props);
        this.state = { searchText: '', result: '' };
    }

    searchWiki() {
        Keyboard.dismiss();
        this.setState({
            result: `Je hebt gezocht op: ${this.state.searchText}.`,
        });
    }

    render() {
        return (
            <View>
                <View style={styles.container}>
                    <TextInput
                        placeholder="Zoekterm"
                        onChangeText={searchText => this.setState({ searchText })}
                        value={this.state.searchText}
                        style={styles.search}
                    />
                    <Button
                        onPress={() => {
                            this.searchWiki();
                        }}
                        title="Zoek informatie"
                    />
                </View>
                <Text style={styles.container}>{this.state.result}</Text>
            </View>
        );
    }
}

Om het scherm ook echt in de app te kunnen gebruiken, voegen we het toe in de navigator in App.js:

...
import WikiScreen from './screens/WikiScreen';
const MainNavigator = createStackNavigator({
  Home: {screen: HomeScreen},  
  Wiki: {screen: WikiScreen},
});
...

Nu het scherm hier geregistreerd staat, werkt de knop ‘open wikischerm’ op het startscherm zoals verwacht. De gebruiker wordt doorgestuurd naar het nieuwe scherm.

Een werkende knop in je mobiele app.

Het nieuwe scherm ‘Wiki’ lijkt qua code op het startscherm, maar naast een knop is er een TextInput-component geïntroduceerd. De tekstinvoer die de gebruiker in dit veld invoert, wordt direct doorgezet naar de ‘state’ van het component met de ‘onChangeText’ listener.

De state is de context van het component. Hierin wordt alle informatie opgeslagen die nodig is voor de functionele werking. Wijzigingen in de state kunnen niet direct in de variabele worden gezet. Door de setState-functie te gebruiken, is React Native op de hoogte van de wijziging. Zo wordt deze wijziging goed doorgevoerd waar de waarde staat gerefereerd.

Netwerkcommunicatie

Het teruggeven van een zoekterm is natuurlijk niet zo interessant als het daadwerkelijk opzoeken van het onderwerp. We voegen daarom in dit laatste onderdeel functionaliteit toe, waarmee de zoekknop een zoekactie start in de informatie van de Nederlandse Wikipedia. Vervang daarvoor de functie searchWiki() door:

...
searchWiki() {
        Keyboard.dismiss();
        fetch(`https://nl.wikipedia.org/w/api.php?action=opensearch&namespace=0&limit=1&format=json&search=${this.state.searchText}`)
            .then(response => response.json())
            .then((responseJson) => {
                if (Array.isArray(responseJson[2]) && responseJson[2].length) {
                    this.setState({
                        result: responseJson[2],
                    });
                } else {
                    this.setState({
                        result: `Er werd geen artikel gevonden voor: ${this.state.searchText}.`,
                    });
                }
            })
            .catch((error) => {
                console.error(error);
                this.setState({
                    result: 'Fout bij het inladen van het artikel.',
                });
            });
    }

De searchWiki()-functie verbergt het toetsenbord met Keyboard.dismiss(). Op die manier blijft het toetsenbord niet in beeld staan na het drukken op de zoek-knop. Vervolgens wordt de zoektekst samen met een omschrijving gekopiëerd naar het state veld result, dat op het scherm wordt weergegeven.

De nieuwe functie ‘searchWiki()’ doet een verzoek naar de REST API van Wikipedia. Als antwoord hierop krijgen we een platte JSON array terug, waarvan het eerste en tweede element bestaan uit de titel en het derde element uit een korte samenvatting van het gevonden artikel. Is dit derde element gevuld met tekst, dan zetten we het antwoord van Wikipedia in de ‘state.result’. Mocht er iets misgaan bij het zoeken of bestaat het artikel niet, dan tonen we hiervoor een melding aan de gebruiker.

De schrijfwijze van de functie kan wat onwennig overkomen. Het is de syntax van JavaScript promises, waarbij telkens het resultaat van een asynchrone functie wordt afgewacht, voordat met ‘then’ de resultaten worden verwerkt.

Eindresultaat van minicursus mobiele app bouwen.

Gefeliciteerd! Met deze laatste stap hebben we de app met navigatie en zoekfunctie voor Wikipedia-onderwerpen voltooid.

Publicatie en verdere verdieping

Ben je enthousiast geworden over het bouwen van apps in React Native en wil je meer weten? Hieronder staan een paar handige links om je verder te helpen met bouwen van aanvullende functionaliteit en de voorbereiding op publicatie in de app stores.

Bij de tutorial van Facebook staat bij het tabblad ‘React Native CLI Quickstart’ hoe je de installatie en configuratie voor Android-publicatie voorbereidt. Ik wens je in ieder geval veel succes met het bouwen van een mobiele app!

P.S. Op de hoogte blijven van alle artikelen, updates, tips en trucs die op ons blog verschijnen? Volg ons via Facebook, Twitter, Instagram, RSS en e-mail!

Deel App Tweet Mail Deel

2 thoughts on “Mobiele apps bouwen met React Native

  1. Han Koot op zei:

    Ik ben bezig om onder een subdomein een react applicatie te bouwen. Deze wil ik laten praten met een mongodb database.

    Kan ik deze ook via directAdmin beschikbaar maken voor gebruikers?

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *