Redux!? Mobx!? It’s time to Fall In Love with Remx

Dror Biran
Wix Engineering
Published in
7 min readNov 7, 2017

Step by Step example for building a simple app with Remx — Flux architecture, through a short, simple, clean and easy to learn API .

Preliminaries: Before you dive into this tutorial, you should be familiarized with the basics of React Native. You can use the official React Native Getting Started guide.

This project follows the guidelines written by Tal Kol in the following article: Redux Step by Step: A Simple and Robust Workflow for Real Life Apps

Note: This tutorial is also part of the official React Native Crash Course by Wix.

What Are We Going To Learn

We are going to use a combination of three, very powerful libraries:

  • remxremx takes the redux (flux) architecture and enforces it through a short, simple, clean and easy to learn API. Almost Zero boilerplate!
  • React Native Navigation — A complete native navigation solution for React Native by Wix.
  • React Native Ui Lib — UI Toolset & Components Library for React Native by Wix

We are only going to view the basics of those libraries. These libraries have a lot to offer so I encourage you to go over the full documentation after we are done :)

What Are We Going To Build

We are going to build a simple Reddit app:

  1. The first screen will display a list of topics
  2. A click on each topic will take you to a screen with all of the topic posts
  3. A click on each post will open this post in your mobile browser.

The full source code for the app is available on GitHub: https://github.com/drorbiran/remx-reddit

Let’s Start Coding

We will start with the following bootstrap project. You can use this repository whenever you want to start a new project based on the power 3 (remx, RNN, UiLib). Clone the repository and follow the short instructions for running the project.

You can also rename the app with just one command using react-native-rename

Once you are all done you will see the following screen in your simulator

Project Structure

The project is organized in the following structure under /src :

  • /src/components — “Dumb” React components that are not connected to the store at all, they receive props from their parents and that’s it. For example, if you have some Button component that will get a color, label and an onPress function as props.
  • /src/screens — All of the app screens which are connected to the store. and an index file in which we will register all of the screens.
  • /src/services — All of the functions that communicate with an external API. In our example, we will have a reddit.js file that will be in charge of all the communication with Reddit API such as getTopics and getPosts.
  • /src/storesAll of the business logic will go here using remx. this folder will be divided according to domains. In our example, we will have one store for topics and a different store for posts. each store will contain 2 files {domain}Store and {domain}Actions. in our example:
  1. /src/stores/topics/topicsStore will hold the topics state, getters and setters.
  2. /src/stores/topics/topicsActionsWill hold all business logic. Every function that is not a simple getter or setter should be in here and use getters and setters to control the store state. for example, fetchTopics will fetch all the topics using the reddit.js service and set the store state accordingly.

Inside the /app.js file we are calling registerScreens() which will register all screen from /src/screens (If you added them to the /src/screens/index.js file) and we are starting a single screen app using React Native Navigation. React Native Navigation has multiple options as a tab based app, you can dig deeper into the documentation in here.

Topics Store

We will start building our app step by step starting with our topicsStore.js file. The first thing that we need to decide, is how the topics state will be structured.
For simplicity we will choose to go with the following structure where the topics are structured in an array:

There are a lot of tips for structuring your app state and I encourage you to read the following post: Avoiding Accidental Complexity When Structuring Your App State. Following these tips will probably lead us not to use arrays and the correct structure for our store should be more like this:

In order to keep our example as simple as possible, and avoiding the need to parse our data, we will stick with arrays (But again it’s important to understand that arrays will not be the smart choice in a real project).

To define our store initial state we will use remx.state function. We will start with an empty topics array and loading will be true (to display a loader until we fetch the topics). your topicsStore.js file should look like this:

In the store, we will also add getters and setters using remx.getters and remx.setters functions. All the functions that are going to return parts of the state should be wrapped within the Getters function and all the functions that are going to change parts of the state should be wrapped within the Setters function.

Getters and Setters can be pretty fancy. Setters can manipulate our store state (For example setting isLoading to true after setting the topics). Getters can parse the data according to how we want to present it (For example extract only the topic title and image from a list of topics). remx actually has an automatic caching mechanism for getters!

In our example, Because we structured our app with arrays, and exactly in the same way that we are going to display and set our data, our getters and setters will be pretty dumb. So our final storeTopics.js file should look like this:

Topics Actions

All of the business logic will go into the topicsActions.js file. We will need a way to fetch all of the topics from Reddit and once we are done, we will need to update the topics state with the new topics that we fetched. In addition, we will need to update loading to false once we are done.

We don’t want to handle the Reddit services until the end so, for now, we will “fake” the data that we are going to receive for Reddit and we will fake the time that it will take using setTimeout (so we will be able to view the loader). your topicsActions.js file should look like this:

and we will fake the reddit.js service to return us a mock data:

Topics List Screen

Yay. Now that we have all the logic that we need we can start working on our first screen topicsList.js. To connect a component to our store we will use remx.connect(mapStateToProps)(MyComponent). In our example, we would be able to access topics and isLoading from this.props.it will look like this (I also removed some boilerplate that came with the bootstrap project):

Let’s Make It (a bit) Pretty

Now that we are all wired up let’s take a little break and give our app a better look. React Native UI Lib will help us with it. This library has tons of useful components that we can use out of the box and you can explore them at GitHub. For example the LoaderScreen , all we need to do is import it and give it the right props, I’m using loaderColor and message. We can also use the UI Lib modifiers and presets for colors, typography, layout and more… Let’s add the LoaderScreen:

Currently, we are displaying the topics list as a raw string. It’s time to move it to FlatList. We will work on the renderList function:

Well…Yep, it still looks terrible. Let’s see how the Ui-Lib can help us. There are multiple options for listItems. I will use the Card component and create a Card for each topic. You can build a card from multiple Card.Section Card.Item and Card.Image

And our Topics screen is almost ready.

Navigating To The Posts Screen

finally NAVIGATION!!! So we need to press on a card, and it will take us to a different screen (In our case the posts screen which we don’t have for now).

Let’s start with creating the PostsList.js screen. We can overwrite the Screen1.js screen that came from the bootstrap project because we don’t really need it anymore. Let’s change its name and make him display a url prop that he will get from Navigation.

And don’t forget that we also need to update the screen name in the src/screens/index.js file so it will register the correct screen.

Now in the TopicsList.js we will use react-native-navigation to push a new screen with navigator.push. we will pass the topic url as a prop to the next screen using passProps. In the future, we will need this url to fetch the relevant posts, but for now, we will just display it to show that indeed it was passed as a prop.

We will change theonPress function in the Card component:

Posts Screen

Working on the posts screen is a very similar process to what we did with the topics screen. We will need to create a new domain src/stores/posts and a new postsStore.js and postsActions.js files. I encourage you to struggle with it by yourselves, it’s a great practice. Repeat the steps that we did with the Topics Screen:

  • Think of how the posts state will look like (title, url, text, img, etc.)
  • Create the initial state, getters and setters
  • Create the action which will fetch the posts
  • In reddit.js just return a mock data that will simulate the data that you will get from Reddit.
  • render the LoaderScreen and FlatList as we did in the TopicsList.js screen.

And We Are Done

The full source code for the app including the reddit.js file with the actual use of Reddit API (I didn’t feel like the implementation of the service is really what this post is all about) is available on GitHub:

This is actually the first tech post that I wrote. So It will be great to get your feedback 🤗

--

--

Dror Biran
Wix Engineering

A Product manager and a Front-end React Native developer at Wix.com