React, Flux, localForage and Saving Data

Remember my vague promise to write an awesome app? The one where I would do something more than just a basic task list like todomvc? Well, I’m progressing. Right now, my HoneyDo application has the ability to edit tasks through a bunch of React components and it loads and saves data from the disk. I haven’t quite got to the point of adding tasks yet – that’s tomorrows project.

Today I want to talk about saving and loading data. I thought that it would be a little bit more efficient as I worked towards a cloud service if I persisted the data I was storing in memory to disk. I want to be able to load up the web page and then see the same tasks as before, so it makes sense to store them locally. However, I’m expecting latency in the process, so I don’t want to repeatedly save for every single change. Changes happen for every single letter in the title, for example. Saving every change would produce a lot of latency. I do want to indicate whether the data has been saved or not, somewhere in the banner.

The Dirty Store

At its core, my flux/TaskStore.js handles an array of models/Task objects with a bunch of methods for CRUD operations. To facilitate the functionality required, I did the following:

  • Added a dirty field to the Task model that can be set and cleared.
  • Added a saving field to the TaskStore to indicate that saving is active.
  • Added code so that when the Task was changed, the dirty flag was set on the Task model.
  • Added an indicator of the dirty status to the TaskListItem.jsx component.

Basically, the tasks now have a dirty flag and the store has a saving indicator.

Loading Tasks

To store tasks persistently, I used the localForage module. This is a Mozilla module that abstracts the various methods of storing data persistently and provides a Promise-based API. It provides the same API as localStorage, but it has two improvements – firstly, it uses Promises so it’s asynchronous out of the box. Secondly, it can store arrays, objects, numbers and so on – localStorage likes strings only. The localForage API handles the serialization for you if needed.

Loading tasks becomes easy. This is taken from the flux/TaskStore.js file:

  loadTasks() {
    localforage.iterate((value, key, iterationNumber) => {
    if (this.tasks.length == 0) {

The loadTasks() method is called in the constructor. If there is nothing there, then I call initializeTasks() which creates three tasks to show off the interface. Note that in the code that is checked in, I have an alternate path. This is done for backwards compatibility and you can generally ignore it.

Saving Tasks

Saving tasks is not as easy:

  saveTasks() {
    // Return immediately if the store is not dirty OR we are already saving
    if (!this.isDirty() || this.saving) {

    // Set the dirty flag to false and the saving flag to true
    this.saving = true; this.changeStore();

    // Loop through the tasks that are dirty and store them
    this.tasks.filter(t => t.dirty).forEach(t => {
      localforage.setItem(, t.serialize());
      t.dirty = false;

    // Now that we are done that, clear the saving flag and change the store
    this.saving = false; this.changeStore();

If the store is not dirty or I am currently saving data, then this method becomes a no-op. I’ll just wait for the next time round. Then there is a definite process to follow.

  • Set up the flags to show the store is saving and push that out to the views
  • Get a list of the dirty tasks
  • Serialize each task and store it, then clear the dirty flag
  • Clear the saving flag and then push the changes out to the views

In this way, we can continue working and recording changes while the saving is happening. Each task is saved independently and asynchronously.

Showing Off Sync Status

I’ve got a component called components/TaskSyncStatus.jsx that shows off the state of the saving process. There are three states. If nothing is displayed, the store is clean (it doesn’t need saving) and saving is not in progress. If the store is dirty but not being saved, I put up an icon and if the store is saving, I put up a spinning icon.

Wrap Up

LocalForage is well worth a look if you need to store persistent data. It abstracts the various APIs and gives you a consistent method of accessing the data contained therein.

You need to think about storing data in pretty much any project. Using persistent storage locally allows you to prep for the eventual move to the cloud.