Four Key Reasons to Learn Markdown
Back-End Leveling UpWriting documentation is fun—really, really fun. I know some engineers may disagree with me, but as a technical writer, creating quality documentation that will...
In part 1 of our series, we created a Node.js backend for our Notifier app that receives messages via a webhook and sends them over a RabbitMQ queue to a worker process, which then saves them to a MongoDB database. This is a good foundation for our Node backend upon which we’ll be able to add live updates in future posts.
Before we do any more work on the backend, let’s create a React Native client app using Expo so we’ll have a frontend that’s ready for a great live-update experience as well. One of Expo’s features is great cross-platform push notification support, so we’ll be able to benefit from that in part 6 of the series.
If you like, you can download the completed client project for part 2.
If you haven’t built an app with Expo before, this tutorial will walk you through running the app on a virtual device on either Android or iOS. You will need to have one of the following installed on your development machine:
Next, install the Expo CLI globally:
$ npm install -g expo-cli
Then create a new project:
$ expo init notifier-client
You’ll be prompted to answer a few questions; choose the following answers:
After the project setup completes, go into the project directory and add a few more dependencies:
$ cd notifier-client $ yarn add axios react-native-elements
Here’s what they’re for:
axios
is a popular HTTP client.react-native-elements
is a UI library that will make our super-simple app look a bit nicer.Next, let’s start the Expo development server:
$ yarn start
This should open Expo’s dev server in your browser. It looks something like this:
If you want to run on Android, make sure you’ve followed Expo’s instructions to start an Android virtual device. If you want to run on iOS, Expo will start the virtual device for you.
Now, in the browser window click either “Run on Android device/emulator” or “Run on iOS Simulator.” In the appropriate virtual device you should see a build progress bar and, when it completes, the message “Open up App.js to start working on your app!”.
Let’s do that thing they just said!
Replace the contents of App.js
with the following:
import React, { Fragment } from 'react'; import { SafeAreaView, StatusBar } from 'react-native'; import { ThemeProvider } from 'react-native-elements'; import MainScreen from './src/MainScreen'; export default function App() { return ( <ThemeProvider> <Fragment> <StatusBar barStyle="dark-content" /> <SafeAreaView style={{ flex: 1 }}> <MainScreen /> </SafeAreaView> </Fragment> </ThemeProvider> ); }
Note that at this point the React Native app won’t build for a few steps.
The changes to App.js
will do the following:
ThemeProvider
so we can use Elements.MainScreen
component we haven’t created yet.Now let’s create that MainScreen
component. Create a src
folder, then a MainScreen.js
inside it, and add the following contents:
import React from 'react'; import { View } from 'react-native'; import MessageList from './MessageList'; export default function MainScreen() { return ( <View style={{ flex: 1 }}> <MessageList /> </View> ); }
This file doesn’t do much yet; we’ll add more to it in a future post. Right now it just displays a MessageList
we haven’t created yet. On to that component!
Create src/MessageList.js
and add the following:
import React, { useState, useEffect } from 'react'; import { FlatList, Platform, View } from 'react-native'; import { ListItem } from 'react-native-elements'; import axios from 'axios'; const httpUrl = Platform.select({ ios: 'http://localhost:3000', android: 'http://10.0.2.2:3000', }); const loadInitialData = async setMessages => { const messages = await axios.get(`${httpUrl}/list`); setMessages(messages.data); }; export default function MessageList() { const [messages, setMessages] = useState([]); useEffect(() => { loadInitialData(setMessages); }, []); return ( <View style={{ flex: 1 }}> <FlatList data={messages} keyExtractor={item => item._id} renderItem={({ item }) => ( <ListItem title={item.text} bottomDivider /> )} /> </View> ); }
Here’s what’s going on here:
messages
state item.loadInitialData
function the first time the component mounts. We pass it the setMessages
function so it can update the state.loadInitialData
makes a web service request and stores the data in the response. The way to make HTTP requests to your local development machine differs between the iOS Simulator (http://localhost
) and Android Emulator (http://10.0.2.2
), so we use React Native’s Platform.select()
function to return the appropriate value for the device we’re on.FlatList
which is React Native’s performant scrollable list. The list contains React Native Elements ListItem
s. For now we just display the text of the message.Run the following command in the Node app folder to take sure our notifier
Node app from part 1 is up:
$ node web
Reload our Expo app on the virtual device:
When the app reloads, you should see a list of the test messages you entered on your server:
With this, the basics of our client app are in place, and we’re set to begin adding live updates across our stack. In the next part we’ll introduce WebSockets that allow us to push updates to the client.
Writing documentation is fun—really, really fun. I know some engineers may disagree with me, but as a technical writer, creating quality documentation that will...
Humanity has come a long way in its technological journey. We have reached the cusp of an age in which the concepts we have...
Go 1.18 has finally landed, and with it comes its own flavor of generics. In a previous post, we went over the accepted proposal and dove...