Offline-First React Native

React Native Vancouver Meetup – Talk Night

About two weeks ago I presented a talk about the offline first React Native in the React Native Vancouver Meetup. Here is a short summary of the talk and the slides for everyone to use.

In the talk, I explained the concerns and tools related to developing React Native apps that work despite a poor connection. I’ve shares some insights which stem from my experience developing a fully featured app used in farmers fields. Working with farmers in their fields meant that we need to deal with poor or no connectivity frequently.

Displaying the connection

There are 50 shades on connectivity when you are dealing with mobile apps in the field.  Causes could be anything from no connection, poor connection, not found (wrong url) or blocked (accessing google maps in China). That’s why it’s important that you tell your users why things aren’t working. To do that, your app needs to know the error codes and have a strategy to deal with them.

503 – Server Error -> Try again later
504 – Timeout -> Try again later
404 – Not Found -> Give up
451 – Unavailable for legal reasons -> Give up

Connection Detection

To be able to understand causes for poor or no connection, you need to detect the connection. You can use React Native’s NetInfo for that.  Here is how you can use it.

const OfflineBanner = ({ netInfo }) => {
return (
netInfo === ‘none’
? <Code />
: null;

const mapState = state => ({
netInfo: state.netInfo,

export default connect(mapState)(NetInfo);

Lazy/Eager Loading

The different between lazy and eager loading is this: When you are lazy loading, you are waiting until when the data is needed, then you will load it. When loading eagerly, you will load all (or most) of the data upfront. But Lazy and Eager loading are not the only two options when dealing with a mobile app.

You can load most of the data upfront and then use background sync to load extra (or updated) data when needed. You can go one step further and persist the data as well.

Persistent Data

When you want to persist data with React Native, you have 3 storage options:

  1. Key/Value
  2. State
  3. Database

You can chose the option that best suits your unique criteria. You can use React Native’s AsyncStorage to set/get items or can use Redux Persist as a performant, and easy to implement way to persist data. Another option is to use realm if you want to use a database for your app. It all depends on what you need in your app.

Handling Large Files

When we are talking about data in an Offline-First mobile app, the size matters. You can divide your data based on its size. We divided our data to Meta Data and Photos. Photos are bigger in size and when you are dealing with poor connection the large data is going to be problematic. Our approach was to sync metadata first and upload larger files last.

Read/Write Responses

There are strategies you can use when reading or writing and there is no connection. For reading, you can use cache. Something like react-native-cached-images can be helpful.

But writes are not as easy! You can be optimistic or pessimistic. Each of the approaches can be good for different scenarios.  In a pessimistic approach, you will be on pending mode until you receive a success message from your write action. In an optimistic approach you will not wait for the write response, instead you will adjust the value if the write action failed, or try again!

Retry Strategy

You need to decide when and how long you are going to retry a failed action.

A Better Solution

The better solution that I found was using redux-offline. Redux offline is a persistent redux store for offline-first applications. It has first-class support for optimistic UI and can be used with React or React Native.

Here is an example of using Redux-Offline

const asyncAction = (id) => ({
type: ‘LOADING’,
meta: {
offline: {
effect: { url: `${someURL}/${id}` },
commit: { type: ‘SUCCESS’, payload: { id }},
rollback: { type: ‘FAILURE’, payload: { id } },

Redux offline is very new and it can get better. For example, id doesn’t currently support actions with middleware. It also doesn’t have background sync or support for immutable data. It can get better, but it’s a good start.



Leave a reply

Your email address will not be published. Required fields are marked *

©[current-year] A.Y.Technologies

Log in with your credentials

Forgot your details?