Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save olivergeorge/9a9d2e1b18e27a0c8c950d64101dd8c4 to your computer and use it in GitHub Desktop.
Save olivergeorge/9a9d2e1b18e27a0c8c950d64101dd8c4 to your computer and use it in GitHub Desktop.

Storing data in the app using react-native-storage

Without a persistent data store our app would lose all state if killed and restarted.

React Native solves this by providing a simple storage system that is global to the app called AsyncStorage. It is recommended that you use an abstraction on top of AsyncStorage so we use sunnylqm/react-native-storage.

tradeoffs

We've introduced a dependency here. It's possible working directly with StorageAsync would have sufficed. See alternative approach.

api

We need to require the new library and add to the rn-api ns

effects

And some new storage related effects

specs

Additionally, we could define some specs to protect us from typos calling our effects.

(ns future-app.rn-api)
(def ReactNative (js/require "react-native"))
(def AsyncStorage (.-AsyncStorage ReactNative))
(def react-native-storage (js/require "react-native-storage"))
(def Storage (.-default react-native-storage))
...
(ns future-app.effects.storage-effects
(:require [future-app.rn-api :as rn-api]
[cljs.reader :refer [read-string]]
[clojure.string :as string]
[re-frame.core :as re-frame]))
(def storage (new rn-api/Storage #js {:storageBackend rn-api/AsyncStorage}))
(defn save-key
[{:keys [key data then-v catch-v]}]
(-> (.save storage #js {:key key :data (pr-str data)})
(.then #(when then-v (re-frame/dispatch then-v)))
(.catch #(when catch-v (re-frame/dispatch (conj catch-v %))))))
(defn load-key
[{:keys [key then-v catch-v]}]
(-> (.load storage #js {:key key})
(.then read-string)
(.then #(when then-v (re-frame/dispatch (conj then-v %))))
(.catch #(when catch-v (re-frame/dispatch (conj catch-v %))))))
(defn remove-key
[{:keys [key]}]
(.remove storage #js {:key key}))
(re-frame/reg-fx :storage/save-key save-key)
(re-frame/reg-fx :storage/load-key load-key)
(re-frame/reg-fx :storage/remove-key remove-key)
(ns future-app.re-frame.effects.storage-effects-specs
(:require [cljs.spec.alpha :as s]
[future-app.re-frame.effects.storage-effects :as storage-effects]))
(s/def ::key (s/and string? #(not (string/includes? % "_"))))
(s/def ::then-v vector?)
(s/def ::catch-v vector?)
(s/fdef save-key :args (s/cat :m (s/keys :req-un [::key ::data] :opt-un [::then-v ::catch-v])))
(s/fdef load-key :args (s/cat :m (s/keys :req-un [::key ::then-v] :opt-un [::catch-v])))
(s/fdef remove-key :args (s/cat :m (s/keys :req-un [::key])))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment