react-vs-lowcode-cover.png

React Native vs low code - developing in React Native

Published at

In this series I will be comparing the developer experience of React Native and the low code platform Outsystems. In my day to day job I am working as an Outsystems developer, but in the past few weeks I’ve been trying to learn React Native as well. I will be comparing development speed, functionalities and the skill level required to get started. Today we will build a basic React Native app, to see what's like to develop in React Native.

This series will be split into 3 blog items, since there is a lot to discuss. In this first part I will show you how to implement some functionality in a demo app. This will give an clear view of how it is to develop in React Native.

The goal

We will be building a simple count down app, which will display a list of events. This was inspired by CodeMentor’s dev project. These dev projects are a great way to enhance your coding skills. The end result will look like the preview down below. Feel free to play around with it.

Getting started

Since I didn’t want to let you build everything, but rather let you code a few bits, I went ahead and made an example repository. You can clone it using git:

$ git clone https://github.com/jan-wagenaar/CountDownRN_challenge.git

I’m using Expo, since that takes away the hassle of setting up the workflow. If you haven’t used that before, check out the installation guide. This is required to build this app.

Implementing a new library

First we will be installing a new library into our repository. We will be using the date picker into our EventForm screen, to be able to pick a date and time. We will be writing a wrapper component around the DatePicker for more flexibility. Use npm to install the DatePicker library from the react native community:

$ npm i @react-native-community/datetimepicker

I did create a basic component already, but now we’re ready to implement the actual functionality. Go to ‘/components/DateTime/datepicker.js’. First we’ll need to import the date picker component. Add the following statement at the top of the document:

import DateTimePicker from '@react-native-community/datetimepicker';

Then, delete everything between the curly braces of the DatePicker component and replace it with this code:

return (
  <DateTimePicker 
       mode="date" 
       value={ date }
       onChange={(event, value) => onChange(value)}
    />
  )

Handling user input using forms

Now we have the Date picker component, let’s move on to implement it in our form. Go to components/screens/EventForm.js and right after the View container of the Name input paste this code:

<View style={styles.date}>
   <Text
      style={styles.label}
    >
    Date
    </Text>
    <View style={styles.datePicker}>
      <DatePicker 
          date={event.date}
          onChange={updateEventDate}
        />
     </View>
   </View>

When an user enters a date in the date picker, the widgets raises an onChange event. This event returns (amongst other things) the date entered. We then will need to set the new date in the forms state. In the updateEventDate function, paste the following code:

setEvent({
   ...event,
   date: date
});

Retrieving data from local database

We want to be able to edit existing events, so we need to retrieve them from our local database. I’m using SQLite to save our events, since it’s easy to work with. We will go deeper into that later, but I have provided the basic methods already. When we open the EventForm screen, we want to retrieve the event by the provided ID. For this use case, React provides lifecycle methods. Since we’re using the functional component flavor of React, we can use useEffect to handle the retrieval of data. Right above the insertEvent function add this code:

useEffect(() => {
  if(route.params.id !== 0) {
    getEventById(route.params.id, function(eventRec) { 
      setEvent({
        ...eventRec[0],
        date: parseISO(eventRec[0].datetime),
        time: parseISO(eventRec[0].datetime),
      })
    })
  }
}, []);

The empty array at the end will ensure it runs only at the first render.

Delete items from our local database

We’re almost there, the last functionality we want to implement is a delete event action. As discussed before, I’m using SQLite to manage our events. This enables to save and retrieve large numbers of events. It’s unlikely we’ll be doing that during testing this particular app, but you may during developing other apps. We could’ve used the React State to save the data, but it would not persist across sessions. The SQLite gives us access to powerful CRUD operations using the SQL language. To demonstrate that, open up the database.js file in the root folder. Scroll down to the deleteEventById function and add this code within the braces:

db.transaction( tx => {
    tx.executeSql( 'DELETE FROM events WHERE ID = (?)', [id] );
    },
    (t, error) => { console.log("db error deleteEvent"); console.log(error);},
    (t, success) => { callBackFunc(); console.log(`Deleted record with id ${id}`) }
  )

Let’s unpack this. The function will create a new database transaction, and will execute the SQL. This SQL statement instructs the database to delete the record matching the ID. If succeeded, the action will execute the success function provided as input. This gives us the possibility to refresh the events list and navigate to the previous screen.

Deleting records is probability the easiest one to implement. Since this app is rather simple, the SQL used is quite basic. But as your app grows, it may be become more complex. Working with SQLite to save your data does pose some challenges though. For example, I choose to save the date and time part of the form to a single date time attribute. This means that I need to parse and map these attributes when retrieving and saving the form. How much data conversions you will have to perform really depends on your data model and types. SQLite uses slightly different data types then JavaScript does, so some mapping is inevitable.

Testing the app

Now we’ve implemented all our functionalities, we can move on to testing the app. Expo is able to manage this part of the workflow, by setting up a test server. This server provides the runtime logic to the Expo Go app. This app functions as a wrapper for the app you made, so you can test it without generating and installing your app. So after installing the Go app, all you need to do is run this command in the terminal:

$ expo start

After expo started the server, you can scan the QR code that appears in the terminal. This will open the Go app and load the app you’ve made. If you’ve made an mistake and errors appear, check out the solution in my Github. I hope you enjoyed this first part of this series. In the next part we’ll develop the same demo app, but then in Outsystems.