This tutorial guides you through the process of creating a simple react-native TODO app with strapi as your backend. You will be able to create, edit and delete TODO’s on a per-user basis by interacting with the REST-API of strapi.
NOTE: This tutorial assumes that you already have an instance of strapi up and running and created a test user. If you don’t, read their getting started guide.
Try it out
The sample app is available on Github
Setting up your backend
Firstly we’ll need to create a new Content-Type named “todo”. For that we need to access our Content-Type Builder and click on “+ Add A Content-Type”.
Now that we have successfully created our new Content-Type we need to add some fields to it.
- title (String, required): The title of the TODO.
- description (String, required): A quick summary of the TODO.
- finshed (Boolean, default: false): If the TODO was finished.
- owner (Relation, required): The User (User-Permissions) that the TODO belongs to.
When you successfully have added the fields to your Content-Type it should look something like this:
Creating the mobile app
Now that we have our API set up, we can concentrate on our mobile app. I suggest you check out react native’s getting started guide if you aren’t familiar with react-native. We’ll have to initialize a new react-native project by running the react-native CLI.
react-native init TodoApp
Running this command will create a new directory with the specified app name that will be the root of your project. But we are not quite happy yet with the project structure, in the base directory of your project you’ll have to create the following folder structure:
Now that we have our project initialized, our structure optimized and our backend running we can add some packages to our app. We’ll use a predefined list of packages I found to work quite well for my needs and there may be alternatives that are better or as good as the ones chosen but you are free to decide this for yourself!
- react-native-paper: A set of components following Google’s Material Design Guidelines
- react-native-vector-icons: Used by react-native-paper to display a gigantic set of icons that fit your needs.
- react-navigation: A library for creating in app navigation and handling navigation intents. Also provides integration with react-native-paper by providing a material themed bottom tab bar.
- react-native-gesture-handler: Required by react-navigation to work properly.
- redux: Redux is a library for handling global state and modify such.
- react-redux: Provides the components needed for redux to work with react-native.
- redux-persist: Enables you to save and persist your state locally on the device. Especially handy for authentication flows.
- async-storage: Asynchronous on device storage
To add the packages install them via yarn:
yarn add react-native-paper react-native-vector-icons react-navigation redux react-redux redux-persist @react-native-community/async-storage react-native-gesture-handler
Creating the models and controllers
Before getting to the Interface of the app we’ll create a model for our TODO, to do so create a new file in ./src/app/models/TodoModel.js. Since this file contains the model for the Content-Type we have created earlier the fields need to be exactly the same.
We’ll do the same for our User Content-Type from the User-Permissions plugin in strapi. So create a file in ./src/app/models/UserModel.js
Now that we have coded our models you may notice we import a file we haven’t created yet, so let’s create those files!
Create the two needed files:
These file are our controllers where we hold our app logic that will be executed when we call our model functions.
Checkmate! now the second controller.
Hope you’re still with me, as you noticed we call our redux store at the end of the UserController.login() and UserController.logout(), this will make more sense in a few moments.
Creating the redux store
To be able to update our UI we need to create a redux store. This store will hold our user data and be persisted if modified. Amazing, right?
- Create the file ./src/redux/Store.js
- Create the file ./src/redux/reducers/UserReducer.js
- Create the file ./src/redux/actions/UserActions.js
Ok! Now that we have created the files we can start creating our store logic, the logic for each store idendity is held in their so called “reducer”.
The reducer can receive an action, this action has a type and an optional payload that you can define on a per-request basis. We’ll need two types of actions that’ll be “USER_SAVE” and “USER_DELETE” that symbolize respective user log in -/out’s. We will not implement USER_DELETE tho.
To call this reducer we will access the previously created UserActions.js file. That holds two actions: saveUser() and deleteUser().
And lastly we have to code our Store.js file. This file not only includes the reducer but also provides the persistence via the previously installed redux-persist library.
Just one more step and your app is redux ready! Add the PersistorGate and Provider components to your App.js file.
Building the navigation
To build our screens we use the previously installed react-navigation package. We’ll have to create a bunch of files, hope you are ready to get your hands dirty!
Once created, fill all Screen files with mock up content so you can distinguish what screen your are currently on.
Building the navigation’s logic
Open up the file Authentication.js created in the last step and create a new SwitchNavigator via the createStackNavigator() method. We use the SwitchNavigator in combination with redux to redirect the user to the login page or the overview page depending on his authentication state.
Including the navigation into our app
Phuu.. That was a bunch of work, time for something rewarding: Import the navigation file into your App.js file and render it as a component. Also add the Provider component of react-native-paper
Now run your project and take a look at your device/emulator and you should see the following screen:
Coding and styling the login screen
Our mockup screen is amazing but I think it’s time to add some functionality to this bad boy.
Now try to login with a strapi user and you’ll land directly on the overview page! Close the app, open it again, and you’ll see that you are directly accessing the overview screen. This is thanks to redux-persist that loads your saved state and passes it to our SwitchNavigator in Authentication.js.
Coding and styling the overview screen
Do you know what’s one of the greatest features of mobile development? Endless lists! And we’re going to create a list that is created for exactly our application. Since the length of such a list is undefined so the number of possible layouts is too!
Lets get started with our list component for wich we’ll create a new file in ./src/components/TodoList.js!
Now that we have our list set up we are just one more step away from completing our app and that is the view that will be reused for each individual child of the data set.
Create a new file in ./src/app/views/TodoView.js
Finally include the Views into the Overview screen created earlier.
We have created a mobile app that supports creating, editing, deleting TODO’s on a user basis and can display them in a paginated list that is always up to date with the data on the server and thus synchronized across devices.